Grunt入门教程(自动任务运行器)

在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命令,按照屏幕提示回答所需模块的名称和版本即可。

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: { / 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代码的三个方法: grunt.initConfig:定义各种模块的参数,每一个成员项对应一个同名模块。
grunt.loadNpmTasks:加载完成任务所需的模块。 grunt.registerTask:定义具体的任务。第一个参数为任务名,第二个参数是一个数组, 表示该任务需要依次使用的模块。default任务名表示,如果直接输入grunt命令,后面不跟任何参数,这时所调用的模块(该例为 jshint,concat和uglify);该例的check任务则表示使用jshint插件对代码进行语法检查。
上面的代码一共加载了四个模块: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({ cssmin: { minify: { expand: true, cwd: ‘css/‘, src: [‘.css', ‘!.min.css'], dest: ‘css/‘, ext: ‘.min.css' }, combine: { files: { ‘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.initConfig

grunt.initConfig方法用于模块配置,它接受一个对象作为参数。该对象的成员与使用的同名模块一一对应。由于我们要配置的是cssmin模块,所以里面有一个cssmin成员(属性)。

cssmin(属性)指向一个对象,该对象又包含多个成员。除了一些系统设定的成员(比如options),其他自定义的成员称为目标 (target)。一个模块可以有多个目标(target),上面代码里面,cssmin模块共有两个目标,一个是“minify”,用于压缩css文 件;另一个是“combine”,用于将多个css文件合并一个文件。

每个目标的具体设置,需要参考该模板的文档。就cssmin来讲,minify目标的参数具体含义如下:

expand:如果设为true,就表示下面文件名的占位符(即号)都要扩展成具体的文件名。
cwd:需要处理的文件(input)所在的目录。 src:表示需要处理的文件。如果采用数组形式,数组的每一项就是一个文件名,可以使用通配符。
dest:表示处理后的文件名或所在目录。 ext:表示处理后的文件后缀名。
除了上面这些参数,还有一些参数也是grunt所有模块通用的。

filter:一个返回布尔值的函数,用于过滤文件名。只有返回值为true的文件,才会被grunt处理。 dot:是否匹配以点号(.)开头的系统文件。
makeBase:如果设置为true,就只匹配文件路径的最后一部分。比如,a?b可以匹配/xyz/123/acb,而不匹配/xyz/acb/123。
关于通配符,含义如下:
:匹配任意数量的字符,不包括/。 ?:匹配单个字符,不包括/。
**:匹配任意数量的字符,包括/。 {}:允许使用逗号分隔的列表,表示“or”(或)关系。
!:用于模式的开头,表示只返回不匹配的情况。
比如,foo/
.js匹配foo目录下面的文件名以.js结尾的文件,foo//.js匹配foo目录和它的所有子目录下面的文件名以.js结尾的文件,!.css表示匹配所有后缀名不为“.css”的文件。

使用通配符设置src属性的更多例子:
(2)grunt.loadNpmTasks

grunt.loadNpmTasks方法载入模块文件。 (3)grunt.registerTask

grunt.registerTask方法定义如何调用具体的任务。“default”任务表示如果不提供参数,直接输入grunt命令,则先运行 “cssmin:minify”,后运行“cssmin:combine”,即先压缩再合并。如果只执行压缩,或者只执行合并,则需要在grunt命令后 面指明“模块名:目标名”。
grunt-contrib-clean:删除文件。
*
grunt-contrib-compass:使用compass编译sass文件。
*
grunt-contrib-concat:合并文件。
*
grunt-contrib-copy:复制文件。
*
grunt-contrib-cssmin:压缩以及合并CSS文件。
*
grunt-contrib-imagemin:图像压缩模块。
*
grunt-contrib-jshint:检查JavaScript语法。
*
grunt-contrib-uglify:压缩以及合并JavaScript文件。
*
grunt-contrib-watch:监视文件变动,做出相应动作。
模块的前缀如果是grunt-contrib,就表示该模块由grunt开发团队维护;如果前缀是grunt(比如grunt-pakmanager),就表示由第三方开发者维护。

以下选几个模块,看看它们配置参数的写法,也就是说如何在grunt.initConfig方法中配置各个模块。

### grunt-contrib-jshint

jshint用来检查语法错误,比如分号的使用是否正确、有没有忘记写括号等等。它在grunt.initConfig方法里面的配置代码如下。
/.js'] },

上面代码先指定jshint的检查项目,eqeqeq表示要用严格相等运算符取代相等运算符,trailing表示行尾不得有多余的空格。然后,指定files属性,表示检查目标是Gruntfile.js文件,以及lib目录的所有子目录下面的JavaScript文件。

### grunt-contrib-concat

concat用来合并同类文件,它不仅可以合并JavaScript文件,还可以合并CSS文件。
.js', dest : ‘js/‘ } },

上面代码中的options属性指定压缩后文件的文件头,以及sourceMap设置;target目标指定输入和输出文件。

### grunt-contrib-copy

copy模块用于复制文件与目录。

copy: { main: { src: ‘src/‘, dest: ‘dest/‘, }, },

上面代码将src子目录(只包含它下面的第一层文件和子目录),拷贝到dest子目录下面(即dest/src目录)。如果要更准确控制拷贝行为,比如只拷贝文件、不拷贝目录、不保持目录结构,可以写成下面这样:

copy: { main: { expand: true, cwd: ‘src/‘, src: ‘*‘, dest: ‘dest/‘, flatten: true, filter: ‘isFile', }, },

grunt-contrib-watch

watch模块用来在后台运行,监听指定事件,然后自动运行指定的任务。

watch: { scripts: { files: ‘/*.js', tasks: ‘jshint', options: { livereload: true, }, }, css: { files: ‘/.sass', tasks: [‘sass'], options: { livereload: true, }, }, },

设置好上面的代码,打开另一个进程,运行grunt watch。此后,任何的js代码变动,文件保存后就会自动运行jshint任务;任何sass文件变动,文件保存后就会自动运行sass任务。

需要注意的是,这两个任务的options参数之中,都设置了livereload,表示任务运行结束后,自动在浏览器中重载(reload)。这需要在浏览器中安装livereload插件。安装后,livereload的默认端口为localhost:35729,但是也可以用livereload: 1337的形式重设端口(localhost:1337)。

### 其他模块

下面是另外一些有用的模块。

(1)grunt-contrib-clean

该模块用于删除文件或目录。

clean: { build: { src: [“path/to/dir/one”, “path/to/dir/two”] } }

(2)grunt-autoprefixer

该模块用于为CSS语句加上浏览器前缀。

autoprefixer: { build: { expand: true, cwd: ‘build', src: [ ‘**/.css' ], dest: ‘build' } },

(3)grunt-contrib-connect

该模块用于在本机运行一个Web Server。

connect: { server: { options: { port: 4000, base: ‘build', hostname: ‘‘ } } }

connect模块会随着grunt运行结束而结束,为了使它一直处于运行状态,可以把它放在watch模块之前运行。因为watch模块需要手动中止,所以connect模块也就会一直运行。

(4)grunt-htmlhint

该模块用于检查HTML语法。

htmlhint: { build: { 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文件。

sass: { build: { options: { style: ‘compressed' }, files: { ‘build/css/master.css': ‘assets/sass/master.scss' } } }

上面代码指定输出文件为build/css/master.css,输入文件为assets/sass/master.scss。

(6)grunt-markdown

该模块用于将markdown文档转为HTML文档。

markdown: { all: { files: [ { expand: true, src: ‘.md', dest: ‘docs/html/‘, ext: ‘.html' } ], options: { template: ‘templates/index.html', } } },

上面代码指定将md后缀名的文件,转为docs/html/目录下的html文件。template属性指定转换时采用的模板,模板样式如下。

<!DOCTYPE html> <html> <head> <title>Document</title> </head> <body> <div id=”main” class=”container”> <%=content%> </div> </body> </html>
{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参数的格式可以是一个对象,也可以是一个数组。

files: { ‘dest/b.js': [‘src/bb.js', ‘src/bbb.js'], ‘dest/b1.js': [‘src/bb1.js', ‘src/bbb1.js'], }, // or files: [ {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({ cssmin: { options: { // }, minify: { // }, combine: { // } } });
grunt # 默认情况下,先压缩后合并 grunt cssmin:minify # 只压缩不合并 grunt css:combine # 只合并不压缩

如果不指明目标,只是指明模块,就表示将所有目标依次运行一遍。

grunt cssmin

## 常用模块设置

grunt的模块已经超过了2000个,且还在快速增加。下面是一些常用的模块(按字母排序)。

*

jshint: { options: { eqeqeq: true, trailing: true }, files: [‘Gruntfile.js', ‘lib/

## 参考链接

同时推荐:http://www.w3cplus.com/tools/writing-awesome-build-script-grunt.html

concat: { js: { src: [‘lib/module1.js', ‘lib/module2.js', ‘lib/plugin.js'], dest: ‘dist/script.js' } css: { 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模块用来压缩代码,减小文件体积。

uglify: { options: { banner: bannerContent, sourceMapRoot: ‘../‘, sourceMap: ‘distrib/‘+name+'.min.js.map', sourceMapUrl: name+'.min.js.map' }, target : { expand: true, cwd: ‘js/origin', src : ‘
(0)

相关推荐

  • 详解Grunt插件之LiveReload实现页面自动刷新(两种方案)

    方案一:grunt-livereload + Chrome Plug-in 优点:安装.配置简单方便. 缺点:需要配合指定的浏览器插件(Firefox也有相关插件,IE么你懂的). 1. 需要安装2个插接件:grunt-contrib-watch.connect-livereload 执行命令: 复制代码 代码如下: npm install --save-dev grunt-contrib-watch connect-livereload 2. 安装浏览器插件:Chrome LiveReload

  • 使用GruntJS链接与压缩多个JavaScript文件过程详解

    自己写了个简单的HTML5 Canvas的图表库,可以支持饼图,折线图,散点图,盒子图 柱状图,同时支持鼠标提示,绘制过程动画效果等.最终我想把这些多个JS文件变成 一个JS文件发布出去,于是我的问题来啦,怎么把这些JS文件搞成一个啊,群里有个 朋友告诉我,GruntJS – JavaScript多文件编译,风格检查,链接与压缩神器.Google了一 把终于帮我完成这个任务,算是入门,分享一下过程. 一什么是GruntJS 不想翻译英文,自己看它的网站吧->http://gruntjs.com/

  • 使用GruntJS构建Web程序之Tasks(任务)篇

    如何自定义Grunt任务 有时我们需要写一些自己的grunt任务,下面是一个具体例子 一.准备 1. 新建一个目录g12. 新建package.json,放入g13. 新建Gruntfile.js,放入g1 package.json 复制代码 代码如下: {    "name": "g1",    "version": "0.1.0",    "author": "@snandy",  

  • 使用GruntJS构建Web程序之安装篇

    它有以下作用 合并JS文件    压缩JS文件    单元测试(基于QUnit)    一句话:完全自动化(automation) 以下是它的安装过程. 一.安装node 参考nodejs入门 (最新的node会自动安装npm) 二.安装grunt命令行工具grunt-cli 使用-g全局安装,这样可以在任何一个目录里使用了.命令: npm install -g grunt-cli 需要注意的是在linux或mac下有时会报没有权限的错误,这时须在前面加一个sudo, 安装后,可以查看改工具的版

  • 配置Grunt的Task时通配符支持和动态生成文件名问题

    copy: { // 这是Task里的其中一个Target dests: { expand: true, cwd: '<%=config.app%>/newFolder', src: ['**/{a*,b*}.html'], dest: '<%=config.dist%>/newFolder', ext: ".shtml", extDot: "first", flatten:true, //去掉中间上当,下面的rename可以再找回来 ren

  • Node.js的项目构建工具Grunt的安装与配置教程

    Grunt 基于 Node.js ,用 JS 开发,这样就可以借助 Node.js 实现跨系统跨平台的桌面端的操作,例如文件操作等等.此外,Grunt 以及它的插件们,都作为一个 包 ,可以用 NPM 安装进行管理. 所以 NPM 生成的 package.json 项目文件,里面可以记录当前项目中用到的 Grunt 插件,而 Grunt 会调用 Gruntfile.js 这个文件,解析里面的任务(task)并执行相应操作. 安装 Grunt-cli 其实是安装 Grunt-cli ,这里安装Gr

  • 学习使用grunt来打包JavaScript和CSS程序的教程

    Java世界里的Maven提供了强大的包依赖管理和构建生命周期管理.在JavaScript的世界里,随着Node.js的流行,JavaScript原生的构建工具已经成为可能. Grunt.js是基于Node.js的自动化任务运行器.Grunt.js结合NPM的包依赖管理,完全可以媲美Maven.Grunt.js天然适合前端应用程序的构建--不仅限于JavaScript项目,同样可以用于其他语言的应用程序构建.越来越多的JavaScript项目已经在使用Grunt,其中最大的使用者包括著名的jQu

  • 基于Node.js的JavaScript项目构建工具gulp的使用教程

    npm install gulp --save-dev 什么是gulp? gulp是新一代的前端项目构建工具,你可以使用gulp及其插件对你的项目代码(less,sass)进行编译,还可以压缩你的js和css代码,甚至压缩你的图片,gulp仅有少量的API,所以非常容易学习. gulp 使用 stream 方式处理内容.Node催生了一批自动化工具,像Bower,Yeoman,Grunt等. gulp和grunt的异同点 易于使用:采用代码优于配置策略,Gulp让简单的事情继续简单,复杂的任务变

  • 使用GruntJS构建Web程序之合并压缩篇

    有如下步骤: 1.新建项目Bejs2.新建文件package.json3.新建文件Gruntfile.js4.命令行执行grunt任务 一.新建项目Bejs源码放在src下,该目录有两个子目录asset和js.js下放selector.js和ajax.js,这在上一篇已经讲了如何合并压缩它们.这篇只关注asset目录,asset目录下放了一些图片和css文件.一会会把两个css资源reset.css和style.css合并,压缩到dest/asset目录.一个合并版本all.css,一个压缩版本

  • 使用GruntJS构建Web程序之构建篇

    大概有如下步骤 新建项目Bejs    新建文件package.json    新建文件Gruntfile.js    命令行执行grunt任务 一.新建项目Bejs 源码放在src下,该目录有两个js文件,selector.js和ajax.js.编译后代码放在dest,这个grunt会自动生成. 二.新建package.json package.json放在根目录下,它包含了该项目的一些元信息,如项目名称.描述.版本号,依赖包等.它应该和源码一样被提交到svn或git. 现在的项目结构如下 p

  • 使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目

    Grunt 简介 Grunt是一款基于js和node.js的构建工具,由于这段时间node.js越来越火爆,grunt拥有丰富的开源社区支持,产生了很多插件.还有一些插件散落在node社区.构建是一个和宽泛的表述,传统理解就是编译.打包.复制,而今,随着技术越来越丰富,构建还包括对前端组件的预处理,比如sass.less预处理成css,css和js的压缩和合并.grunt的插件可以很好的支持这些新的构建概念,而且更为适合用开源技术堆砌的项目. 虽然Grunt更多的用于程序构建,但是本质上Grun

  • 使用Grunt.js管理你项目的应用说明

    Grunt.js是什么?Grunt.js是一个Javascript Task Runner(Javascript任务运行器),其基于NodeJS,可用于自动化构建.测试.生成文档的项目管理工具. Grunt.js并不是仅仅是构建工具,实际上他只是任务运行器,管理每个子任务的自动化运行,我们还能使用他做更多东西. 为什么使用Grunt.js?简单的说:为了自动化.对于前端项目,例如: •为了明确模块分工,我们可能会将Javascript代码拆成很小很小的一个个js文件,但是我们知道,在最终页面上,

随机推荐