Reputation: 407
I am struggling to understand how I can pass a partial filename from the grunt command line, in order to run a task (from an installed grunt module) on a particular file.
What I want to be able to do is configure a series of tasks to take filename parameter from the command line.
I've tried reworking the final example on this page http://chrisawren.com/posts/Advanced-Grunt-tooling but I'm kind of stabbing in the dark a bit. Thought someone would have a quick answer.
Here is my Gruntfile:
module.exports = function (grunt) {
grunt.initConfig({
globalConfig: globalConfig,
uglify: {
js: {
options: {
mangle: true
},
files: {
'js/<%= globalConfig.file %>.min.js': ['js/<%= globalConfig.file %>.js']
}
}
},
});
// Load tasks so we can use them
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('go', 'Runs a task on a specified file', function (fileName){
globalConfig.file = fileName;
grunt.task.run('uglify:js');
});
};
I attempt to run it from the command line like this:
grunt go:app
to target js/app.js
I get this error:
Aborted due to warnings.
roberts-mbp:150212 - Grunt Tasks robthwaites$ grunt go:app
Loading "Gruntfile.js" tasks...ERROR
>> ReferenceError: globalConfig is not defined
Warning: Task "go:app" not found. Use --force to continue.
Thanks
Upvotes: 4
Views: 1583
Reputation: 407
I the end I was able to accomplish what I wanted like this, but not sure if this is a standard way.
What I was failing to do was declare the globalConfig variable globally first, so that I could redefine it from the Terminal as I ran my grunt task.
Here is an example. When working with HTML emails I need to:
The point is, if I am working on several different HTMl emails in the same project, I need to be able to run all these tasks on html files one-by-one, as needed. The Gruntfile below allows me to do this.
What this does:
If you enter into terminal grunt
It will simply run the sass task, which processes all sass files - no file parameter needed from Terminal.
However, if I wish to run a series of processes on a single html file, I enter grunt process:fileName
with fileName being the name of the html file without the .html extension.
You will notice that the only tasks that require the fileName are actually include-replace and premailer. However, I still want to run al the other CSS cleanup tasks prior to targetting my chosen file.
The key is:
Hope that helps someone.
module.exports = function (grunt) {
var globalConfig = {
file: 'index' // this is the default value, for a single project.
}
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// load the globalConfig variables
globalConfig: globalConfig,
sass: {
dev: {
files: [{
expand: true,
cwd: 'scss',
src: ['*.scss'],
dest: 'css',
ext: '.css'
}]
}
},
cssmin: {
options: {
keepSpecialComments: 0,
keepBreaks: true,
advanced: false
},
target: {
files: [{
expand: true,
cwd: 'css',
src: '*.css',
dest: 'css',
ext: '.css'
}]
}
},
autoprefixer: {
css: {
src: "css/*.css"
}
},
includereplace: {
your_target: {
options: {
prefix: '\\/\\* ',
suffix: ' \\*\\/',
},
files: {
'inline/<%= globalConfig.file %>-inline.html': ['<%= globalConfig.file %>.html']
}
}
},
premailer: {
main: {
options: {
verbose: true,
preserveStyles: true,
},
src: 'inline/<%= globalConfig.file %>-inline.html',
dest: 'inline/<%= globalConfig.file %>-inline.html'
}
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-include-replace');
grunt.loadNpmTasks('grunt-premailer');
grunt.registerTask('default', 'sass');
grunt.registerTask('process', 'Runs all processing tasks on a specific file to produce inlined file', function (fileName) {
globalConfig.file = fileName;
grunt.task.run('sass', 'autoprefixer', 'cssmin', 'includereplace', 'premailer');
});
}
EDIT: Obviously at the moment this accepts only one parameter I beleive. In other use cases the grunt.option version above could give more functionality, being able to submit several parameters in one command. I will continue to experiment with grunt.option if I find the need to do this.
Upvotes: 1
Reputation: 260
you can use grunt.option.
your grunt register task will look like this.
> grunt.option('fileName'); grunt.registerTask('go', 'Runs a task on a
> specified file', function (){
> grunt.task.run('uglify:js');
> });
your grunt configuration will be
module.exports = function (grunt) {
var fileName=grunt.option('fileName');
grunt.initConfig({
uglify: {
js: {
options: {
mangle: true
},
files: {
'js/fileName.min.js': ['js/fileName.js']
}
}
},
});
command to run the task from terminal:
$ grunt go --fileName='xyzfile'
Upvotes: 8