如何战争雷霆自定义任务Grunt任务

grunt入门讲解4:如何创建task(任务) - chaojidan - 博客园
每当运行Grunt时, 你可以为其指定一个或多个任务, 这些任务用于告诉Grunt你想要它做什么事情。
如果你没有指定一个任务,并且你已经定义一个名为 "default" 的任务,那么该任务将会默认被执行。
如果指定了一个任务列表taskList,新任务名taskName将是这一个或多个指定任务的别名。当运行此 "任务别名" 时,在taskList&中指定的每个任务都会按照其出现的顺序依次执行。taskList参数必须是一个任务数组。grunt.registerTask(taskName, taskList)
举个例子:
grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
上面的任务别名案例中定义了一个 'default' 任务,如果运行Grunt时没有指定任何任务,它将自动执行'jshint'、'qunit'、'concat' 和 'uglify' 任务。
还可以给任务指定参数。在下面的例子中,别名 "dist" 将执行 "concat" 和 "uglify" 两个任务,并且它们都带有一个 "dist" 参数:
grunt.registerTask('dist', ['concat:dist', 'uglify:dist']);
当运行一个多任务时,Grunt会自动从项目的配置对象中查找同名属性。多任务可以有多个配置,并且可以使用任意命名的'targets'。举个例子:
grunt.initConfig({
foo: [1, 2, 3],
bar: 'hello world',
baz: false
grunt.registerMultiTask('log', 'Log stuff.', function() {
grunt.log.writeln(this.target + ': ' + this.data);
如果通过grunt log:foo运行Grunt,它会输出foo: 1,2,3;如果通过grunt log:bar来运行Grunt, 它会输出bar: hello world。然而如果通过grunt log运行Grunt, 它会输出foo: 1,2,3,然后是bar: hello world,最后是baz: false(任务目标会按照指定的顺序进行处理)。
"基本" 任务
当一个基本任务执行时,Grunt并不会检查配置和环境 -- 它仅仅执行指定的任务函数,并传递任何使用冒号分割的参数作为函数的参数。举个例子:
grunt.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) {
if (arguments.length === 0) {
grunt.log.writeln(this.name + ", no args");
grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);
如果执行&grunt foo:testing:123,将输出日志&foo, testing 123。 如果执行这个任务时不传递参数,只是执行&grunt foo,那么将输出日志&foo, no args。
自定义任务
如果你的任务没有遵循 "多任务" 结构,那就可以使用自定义任务。比如:
grunt.registerTask('default', 'My "default" task description.', function() {
grunt.log.writeln('Currently running the "default" task.');
任务的其他特性
在一个任务内部,你可以执行其他的任务。比如:
grunt.registerTask('foo', 'My "foo" task.', function() {
// Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
grunt.task.run('bar', 'baz');
grunt.task.run(['bar', 'baz']);
任务也可以是异步的。比如:
grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() {
// Force task into async mode and grab a handle to the "done" function.
var done = this.async();
// Run some sync stuff.
grunt.log.writeln('Processing task...');
// And some async stuff.
setTimeout(function() {
grunt.log.writeln('All done!');
任务也可以访问它们自身名称和参数。比如:
grunt.registerTask('foo', 'My "foo" task.', function(a, b) {
grunt.log.writeln(this.name, a, b);
// grunt foo
logs: "foo", undefined, undefined
// grunt foo:bar
logs: "foo", "bar", undefined
// grunt foo:bar:baz
logs: "foo", "bar", "baz"
如果任务在执行时记录到任何错误,那么任务就会失败。当任务失败时,所有的后续任务都将终止。比如:
grunt.registerTask('foo', 'My "foo" task.', function() {
return false;
grunt.registerTask('bar', 'My "bar" task.', function() {
// 如果"foo"任务运行失败或者没有运行则任务失败。
grunt.task.requires('foo');
// 如果"foo"任务运行成功则执行这里的代码。
grunt.log.writeln('Hello, world.');
// grunt foo bar
没有输出,bar任务没有运行,因为"foo"失败,所以它后面的任务都将终止运行。
// grunt bar
没有输出,bar任务运行,但运动到一半就停止了,因为"foo"从未运行,所以foo任务失败,失败后,bar任务也就停止了,因此没有输出。
注意 grunt.task.requires 并不会真正的运行其他任务,它仅仅检查其它任务是否已经执行,并且没有失败。
任务还可以访问配置属性。比如:
grunt.registerTask('foo', 'My "foo" task.', function() {
// 记录属性值,如果属性未定义(undefined)则返回null。
grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name'));
// 同样的记录属性值,如果属性未定义(undefined)则返回null。
grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name']));
如果任务需要的配置属性不存在,其也会失败。比如:
grunt.registerTask('foo', 'My "foo" task.', function() {
// 如果缺少"meta.name"配置属性则任务失败。
grunt.config.requires('meta.name');
// 如果缺少"mata.name"配置属性则任务同样失败。
grunt.config.requires(['meta', 'name']);
// 根据情况记录日志。
grunt.log.writeln('This will only log if meta.name is defined in the config.');
为什么我的异步task没有完成?如果发生这种情况,可能是由于你忘记调用 this.async 方法来告诉Grunt你的任务是异步的。为了简单起见,Grunt使用同步的编码风格,可以在task体中通过调用 this.async() 将其转换为异步的。
注意,传递 false 给 done() 函数就会告诉Grunt你的任务已经失败。
grunt.registerTask('asyncme', 'My asynchronous task.', function() {
var done = this.async();
setTimeout(function() {1759人阅读
前端(240)
来源:/tool/grunt.html
Grunt:任务自动管理工具
来自,by 阮一峰
在Javascript的开发过程中,经常会遇到一些重复性的任务,比如合并文件、压缩代码、检查语法错误、将Sass代码转成CSS代码等等。通常,我们需要使用不同的工具,来完成不同的任务,既重复劳动又非常耗时。Grunt就是为了解决这个问题而发明的工具,可以帮助我们自动管理和运行各种任务。
简单说,Grunt是一个自动任务运行器,会按照预先设定的顺序自动运行一系列的任务。这可以简化工作流程,减轻重复性工作带来的负担。
Grunt基于Node.js,安装之前要先安装Node.js,然后运行下面的命令。
sudo npm install grunt-cli -g
grunt-cli表示安装的是grunt的命令行界面,参数g表示全局安装。
Grunt使用模块结构,除了安装命令行界面以外,还要根据需要安装相应的模块。这些模块应该采用局部安装,因为不同项目可能需要同一个模块的不同版本。
首先,在项目的根目录下,创建一个文本文件package.json,指定当前项目所需的模块。下面就是一个例子。
&name&: &my-project-name&,
&version&: &0.1.0&,
&author&: &Your Name&,
&devDependencies&: {
&grunt&: &0.x.x&,
&grunt-contrib-jshint&: &*&,
&grunt-contrib-concat&: &~0.1.1&,
&grunt-contrib-uglify&: &~0.1.0&,
&grunt-contrib-watch&: &~0.1.4&
上面这个package.json文件中,除了注明项目的名称和版本以外,还在devDependencies属性中指定了项目依赖的grunt模块和版本:grunt核心模块为最新的0.x.x版,jshint插件为最新版本,concat插件不低于0.1.1版,uglify插件不低于0.1.0版,watch插件不低于0.1.4版。
然后,在项目的根目录下运行下面的命令,这些插件就会被自动安装在node_modules子目录。
npm install
上面这种方法是针对已有package.json的情况。如果想要自动生成package.json文件,可以使用npm init命令,按照屏幕提示回答所需模块的名称和版本即可。
如果已有的package.json文件不包括Grunt模块,可以在直接安装Grunt模块的时候,加上--save-dev参数,该模块就会自动被加入package.json文件。
npm install &module& --save-dev
比如,对应上面package.json文件指定的模块,需要运行以下npm命令。
npm install grunt --save-dev
npm install grunt-contrib-jshint --save-dev
npm install grunt-contrib-concat --save-dev
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-watch --save-dev
命令脚本文件Gruntfile.js
模块安装完以后,下一步在项目的根目录下,新建脚本文件Gruntfile.js。它是grunt的配置文件,就好像package.json是npm的配置文件一样。Gruntfile.js就是一般的Node.js模块的写法。
module.exports = function(grunt) {
// 配置Grunt各种模块的参数
grunt.initConfig({
jshint: { /* jshint的参数 */ },
concat: { /* concat的参数 */ },
uglify: { /* uglify的参数 */ },
{ /* watch的参数 */ }
// 从node_modules目录加载模块文件
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
// 每行registerTask定义一个任务
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
grunt.registerTask('check', ['jshint']);
上面的代码用到了grunt代码的三个方法:
上面的代码一共加载了四个模块:jshint(检查语法错误)、concat(合并文件)、uglify(压缩代码)和watch(自动执行)。接下来,有两种使用方法。
(1)命令行执行某个模块,比如
grunt jshint
上面代码表示运行jshint模块。
(2)命令行执行某个任务。比如
grunt check
上面代码表示运行check任务。如果运行成功,就会显示“Done, without errors.”。
如果没有给出任务名,只键入grunt,就表示执行默认的default任务。
Gruntfile.js实例:grunt-contrib-cssmin模块
下面通过cssmin模块,演示如何编写Gruntfile.js文件。cssmin模块的作用是最小化CSS文件。
首先,在项目的根目录下安装该模块。
npm install grunt-contrib-cssmin --save-dev
然后,新建文件Gruntfile.js。
module.exports = function(grunt) {
grunt.initConfig({
expand: true,
cwd: 'css/',
src: ['*.css', '!*.min.css'],
dest: 'css/',
ext: '.min.css'
combine: {
'css/out.min.css': ['css/part1.min.css', 'css/part2.min.css']
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', ['cssmin:minify','cssmin:combine']);
下面详细解释上面代码中的三个方法,下面一个个来看。
(1)grunt.loadNpmTasks
grunt.loadNpmTasks方法载入模块文件。
grunt.loadNpmTasks('grunt-contrib-cssmin');
你需要使用几个模块,这里就要写几条grunt.loadNpmTasks语句,将各个模块一一加载。
如果加载模块很多,这部分会非常冗长。而且,还存在一个问题,就是凡是在这里加载的模块,也同时出现在package.json文件中。如果使用npm命令卸载模块以后,模块会自动从package.json文件中消失,但是必须手动从Gruntfile.js文件中清除,这样很不方便,一旦忘记,还会出现运行错误。这里有一个解决办法,就是安装load-grunt-tasks模块,然后在Gruntfile.js文件中,用下面的语句替代所有的grunt.loadNpmTasks语句。
require('load-grunt-tasks')(grunt);
这条语句的作用是自动分析package.json文件,自动加载所找到的grunt模块。
(2)grunt.initConfig
grunt.initConfig方法用于模块配置,它接受一个对象作为参数。该对象的成员与使用的同名模块一一对应。由于我们要配置的是cssmin模块,所以里面有一个cssmin成员(属性)。
cssmin(属性)指向一个对象,该对象又包含多个成员。除了一些系统设定的成员(比如options),其他自定义的成员称为目标(target)。一个模块可以有多个目标(target),上面代码里面,cssmin模块共有两个目标,一个是“minify”,用于压缩css文件;另一个是“combine”,用于将多个css文件合并一个文件。
每个目标的具体设置,需要参考该模板的文档。就cssmin来讲,minify目标的参数具体含义如下:
除了上面这些参数,还有一些参数也是grunt所有模块通用的。
关于通配符,含义如下:
比如,foo/*.js匹配foo目录下面的文件名以.js结尾的文件,foo/**/*.js匹配foo目录和它的所有子目录下面的文件名以.js结尾的文件,!*.css表示匹配所有后缀名不为“.css”的文件。
使用通配符设置src属性的更多例子:
{src: 'foo/th*.js'}grunt-contrib-uglify
{src: 'foo/{a,b}*.js'}
{src: ['foo/a*.js', 'foo/b*.js']}
至于combine目标,就只有一个files参数,表示输出文件是css子目录下的out.min.css,输入文件则是css子目录下的part1.min.css和part2.min.css。
files参数的格式可以是一个对象,也可以是一个数组。
'dest/b.js': ['src/bb.js', 'src/bbb.js'],
'dest/b1.js': ['src/bb1.js', 'src/bbb1.js'],
{src: ['src/aa.js', 'src/aaa.js'], dest: 'dest/a.js'},
{src: ['src/aa1.js', 'src/aaa1.js'], dest: 'dest/a1.js'},
如果minify目标和combine目标的属性设置有重合的部分,可以另行定义一个与minify和combine平行的options属性。
grunt.initConfig({
options: { /* ... */ },
minify: { /* ... */ },
combine: { /* ... */ }
(3)grunt.registerTask
grunt.registerTask方法定义如何调用具体的任务。“default”任务表示如果不提供参数,直接输入grunt命令,则先运行“cssmin:minify”,后运行“cssmin:combine”,即先压缩再合并。如果只执行压缩,或者只执行合并,则需要在grunt命令后面指明“模块名:目标名”。
grunt # 默认情况下,先压缩后合并
grunt cssmin:minify # 只压缩不合并
grunt css:combine # 只合并不压缩
如果不指明目标,只是指明模块,就表示将所有目标依次运行一遍。
grunt cssmin
常用模块设置
grunt的已经超过了2000个,且还在快速增加。下面是一些常用的模块(按字母排序)。
模块的前缀如果是grunt-contrib,就表示该模块由grunt开发团队维护;如果前缀是grunt(比如grunt-pakmanager),就表示由第三方开发者维护。
以下选几个模块,看看它们配置参数的写法,也就是说如何在grunt.initConfig方法中配置各个模块。
grunt-contrib-jshint
jshint用来检查语法错误,比如分号的使用是否正确、有没有忘记写括号等等。它在grunt.initConfig方法里面的配置代码如下。
options: {
eqeqeq: true,
trailing: true
files: ['Gruntfile.js', 'lib/**/*.js']
上面代码先指定jshint的,eqeqeq表示要用严格相等运算符取代相等运算符,trailing表示行尾不得有多余的空格。然后,指定files属性,表示检查目标是Gruntfile.js文件,以及lib目录的所有子目录下面的JavaScript文件。
grunt-contrib-concat
concat用来合并同类文件,它不仅可以合并JavaScript文件,还可以合并CSS文件。
src: ['lib/module1.js', 'lib/module2.js', 'lib/plugin.js'],
dest: 'dist/script.js'
src: ['style/normalize.css', 'style/base.css', 'style/theme.css'],
dest: 'dist/screen.css'
js目标用于合并JavaScript文件,css目标用语合并CSS文件。两者的src属性指定需要合并的文件(input),dest属性指定输出的目标文件(output)。
grunt-contrib-uglify
uglify模块用来压缩代码,减小文件体积。
options: {
banner: bannerContent,
sourceMapRoot: '../',
sourceMap: 'distrib/'+name+'.min.js.map',
sourceMapUrl: name+'.min.js.map'
target : {
expand: true,
cwd: 'js/origin',
src : '*.js',
dest : 'js/'
上面代码中的options属性指定压缩后文件的文件头,以及sourceMap设置;target目标指定输入和输出文件。
grunt-contrib-copy
用于复制文件与目录。
src: 'src/*',
dest: 'dest/',
上面代码将src子目录(只包含它下面的第一层文件和子目录),拷贝到dest子目录下面(即dest/src目录)。如果要更准确控制拷贝行为,比如只拷贝文件、不拷贝目录、不保持目录结构,可以写成下面这样:
expand: true,
cwd: 'src/',
src: '**',
dest: 'dest/',
flatten: true,
filter: 'isFile',
grunt-contrib-watch
用来在后台运行,监听指定事件,然后自动运行指定的任务。
scripts: {
files: '**/*.js',
tasks: 'jshint',
options: {
livereload: true,
files: '**/*.sass',
tasks: ['sass'],
options: {
livereload: true,
设置好上面的代码,打开另一个进程,运行grunt watch。此后,任何的js代码变动,文件保存后就会自动运行jshint任务;任何sass文件变动,文件保存后就会自动运行sass任务。
需要注意的是,这两个任务的options参数之中,都设置了livereload,表示任务运行结束后,自动在浏览器中重载(reload)。这需要在浏览器中安装。安装后,livereload的默认端口为localhost:35729,但是也可以用livereload:
1337的形式重设端口(localhost:1337)。
下面是另外一些有用的模块。
(1)grunt-contrib-clean
该模块用于删除文件或目录。
src: [&path/to/dir/one&, &path/to/dir/two&]
(2)grunt-autoprefixer
该模块用于为CSS语句加上浏览器前缀。
autoprefixer: {
expand: true,
cwd: 'build',
src: [ '**/*.css' ],
dest: 'build'
(3)grunt-contrib-connect
该模块用于在本机运行一个Web Server。
connect: {
options: {
port: 4000,
base: 'build',
hostname: '*'
connect模块会随着grunt运行结束而结束,为了使它一直处于运行状态,可以把它放在watch模块之前运行。因为watch模块需要手动中止,所以connect模块也就会一直运行。
(4)grunt-htmlhint
该模块用于检查HTML语法。
htmlhint: {
options: {
'tag-pair': true,
'tagname-lowercase': true,
'attr-lowercase': true,
'attr-value-double-quotes': true,
'spec-char-escape': true,
'id-unique': true,
'head-script-disabled': true,
src: ['index.html']
上面代码用于检查index.html文件:HTML标记是否配对、标记名和属性名是否小写、属性值是否包括在双引号之中、特殊字符是否转义、HTML元素的id属性是否为唯一值、head部分是否没有script标记。
(5)grunt-contrib-sass模块
该模块用于将SASS文件转为CSS文件。
options: {
style: 'compressed'
'build/css/master.css': 'assets/sass/master.scss'
上面代码指定输出文件为build/css/master.css,输入文件为assets/sass/master.scss。
(6)grunt-markdown
该模块用于将markdown文档转为HTML文档。
markdown: {
expand: true,
src: '*.md',
dest: 'docs/html/',
ext: '.html'
options: {
template: 'templates/index.html',
上面代码指定将md后缀名的文件,转为docs/html/目录下的html文件。template属性指定转换时采用的模板,模板样式如下。
&!DOCTYPE html&
&title&Document&/title&
&div id=&main& class=&container&&
&%=content%&
Frederic Hemberger,&
Mária Jur?ovi?ová,&
Ben Briggs,
Swapnil Mishra,&
AJ ONeal,&
Grunt Documentation,&
Landon Schropp,&
Mike Cunsolo,&
Matt Bailey,&
Paul Bakaus,&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1173004次
积分:13047
积分:13047
排名:第800名
原创:253篇
转载:416篇
评论:193条
(8)(3)(2)(11)(2)(5)(6)(1)(4)(25)(21)(12)(12)(16)(6)(22)(33)(20)(31)(10)(4)(5)(19)(10)(4)(14)(16)(10)(24)(8)(63)(19)(25)(22)(44)(13)(7)(15)(15)(22)(14)(41)(11)}

我要回帖

更多关于 战争雷霆自定义任务 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信