Grunt高级用

  • 时间:2018-09-11 22:03 作者:叩丁狼教育stef 来源:叩丁狼教育stef 阅读:101
  • 扫一扫,手机访问
摘要:一,Grunt的运转机制Grunt拥有数量庞大的插件,这些插件能够帮助我们解决开发中遇到的绝大多数构建任务,比方代码的预编译、压缩、代码检查、单元测试等。但为什么在终端输入Grunt相关命令,就能够执行对应的任务,Grunt究竟是怎样运转的?这些知识对于深入研究Grunt非常重要,下面我们从Grun
Grunt高级用

一,Grunt的运转机制

Grunt拥有数量庞大的插件,这些插件能够帮助我们解决开发中遇到的绝大多数构建任务,比方代码的预编译、压缩、代码检查、单元测试等。但为什么在终端输入Grunt相关命令,就能够执行对应的任务,Grunt究竟是怎样运转的?这些知识对于深入研究Grunt非常重要,下面我们从Grunt运转的组件和运转机制两方面来开展探讨。

2.1 Grunt的核心组件

node和npm

Grunt项目基于Node.js,Grunt和相关的插件都通过 npm 安装并管理。

Grunt-cli

Grunt命令行使用于调使用与Gruntfile文件在同一目录中的 Grunt板块,通过-g参数把Grunt命令行安装到全局环境中,这样的话在所有文件目录中都可以调使用grunt相关的命令。

在命令行中运行Grunt 相关命令时(比方 $grunt default),内部会根据node提供的require系统查找来当前目录中安装的 Grunt,假如找到那么加载,并把加载的grunt作为参数传递到Gruntfile文件中,而后执行指定的任务。

Task

Task就是任务的意思,grunt支持自己设置任务,也支持用现成的插件任务。比方向控制台输出一句问候这可以被认为是一个Task,对所有的js文件进行压缩这也是一个Task,通常任务(Task)都是可配置的。

Grunt本地依赖

安装了grunt命令行不等于就安装了grunt,这只是让我们拥有了在命令行中用grunt相关命令的能力,对于每个需要用grunt的工程,依然需要为其配置grunt本地依赖。

Grunt插件(Plugins)

Grunt插件是一系列能够使用于不同项目的可配置任务的集合。Grunt插件通常以npm包的形式发布。Grunt官网的插件列表列出了所有可使用的Grunt插件,截止当前的插件数量为6,393个,其中带有contrib前缀的插件由Grunt官方开发和维护。

package.json文件

package.json文件使用于被npm存储项目的元数据,以便将此项目发布为npm板块。我们可以在此文件中列出项目依赖的Grunt和Grunt插件,保存在devDependencies(开发依赖)配置字段内,我们可以通过$ npm install命令来加载该文件中的所有依赖项。

Gruntfile.js文件

Gruntfile文件是Grunt项目中最核心的文件,该文件同package.json文件一起存放在项目的根目录中,主要使用来配置或者定义任务(task)并加载Grunt插件。标准的grunt项目中必需拥有package.json和Gruntfile这两个文件。

node_modules文件夹

node_modules文件目录存放着从远程仓库下载的grunt以及所有相关的grunt插件。

2.2 Grunt的运转机制

Grunt高级用

上面给出了Grunt项目中各主要组件的关系图示,是根据个人的了解绘制的,所以可能并非完全精确,但基本上已经能够说清楚Grunt的运转机制了。

我们在用Grunt作为项目构建工具的时候,所做的事情大概可以分成三块:准备、配置、执行。

① 准备阶段

准备阶段主要进行以下操作

? node环境的安装、npm的安装(在安装node的时候默认安装)

? grunt-cli命令行的安装(通过$ npm install -g grunt-cli命令)

? 创立package.json文件(手动创立或者通过$ npm init命令交互式创立)

? 配置grunt本地依赖(通过$ npm install grunt --save-dev下载grunt到项目)

? 安装需要的grunt插件(通过$ npm install grunt-contrib-xx --save-dev命令把需要的插件下载到node_modules目录)

② 配置阶段

配置阶段主要就是创立和编辑Gruntfile文件,在该文件中接收grunt参数并配置Task,注册Task。Task简单说就是任务的意思,我们可以自己设置任务,也可以直接用现成的、少量其余优秀开发者定义好并打包为node板块发布的任务(其实就是grunt插件)。

一般来说,我们总是通过grunt为我们提供的grunt.initConfig方法来对Task(插件)进行配置,假如是该Task是Grunt插件那么还需要先从node_modules目录中加载。

假如对多个Task的执行有指定的顺序或者者依赖关系,那么我们可以通过grunt.registerTask方法来注册Task。

③ 执行阶段

在执行阶段,通过在命令行中输入$ grunt task名称的方式来执行指定的任务。

执行Task的时候,可以单个执行,例如:

$ grunt taskName1

$ grunt taskName2

也可以使用单条命令执行多个Task,每个Task都将按照参数的传入顺序依次执行,例如:

$ grunt taskName1 taskName2

在用构建工具的时候,这些Task具体怎样执行,执行的顺序等并非是固定不变的,需要结合特定的需求来特殊解决。假如总是有一组Task需要按顺序执行,一般可以用grunt.registerTask方法来给这组Task设置个别名,这一组的Task以数组的形式传递。

例如:要依次执行js文件的合并、语法检查、代码压缩、css代码压缩等任务,则配置好相关Task后可以像下面这样来设置。

 grunt.registerTask("customTask",["concat","jshint","uglify","cssmin"]);

要执行这组任务的时候,直接执行$ grunt customTask命令就可。

二,Grunt的用进阶

Grunt自己设置任务

在用Grunt的时候,可以先到Grunt官网的插件列表搜索能否有适合自己项目的Grunt插件,假如有那么建议直接用,假如没有那么开发者可以尝试自己设置任务或者者是自己创立对应的插件。Grunt的插件其实就是少量封装好的任务(Task),没有什么稀奇的,Grunt支持自己设置任务,而且方式非常简单。

假如我们需要定义一个任务,向控制台里输出字符串信息,那么在package.json文件、Gruntfile文件已经创立且grunt本地依赖已安装的前提下,如下编辑Gruntfile文件就可:

//包装函数
module.exports = function (grunt) {
//(1)自己设置任务(一)
//向控制台输出:hello 文顶顶
//第一个参数:任务的名称(Task)
//第二个参数:具体的任务内容
grunt.registerTask("hello",function () {
grunt.log.writeln("hello 文顶顶");
});
//(2)自己设置任务(二)
grunt.registerTask("football",function () {
grunt.log.writeln("皇家马德里: how are you!");
grunt.log.writeln("尤文图斯: how old are you!");
});
};

终端输入命令执行任务,可以单个执行,也可以一起执行,下面给出具体执行情况

wendingding:02-Grunt_Test wendingding$ grunt hello
Running "hello" task
hello 文顶顶
Done.
wendingding:02-Grunt_Test wendingding$ grunt football
Running "football" task
皇家马德里: how are you!
尤文图斯: how old are you!
Done.
wendingding:02-Grunt_Test wendingding$ grunt hello football
Running "hello" task
hello 文顶顶
Running "football" task
皇家马德里: how are you!
尤文图斯: how old are you!
Done.

通过上面的代码我们可以看到,自己设置任务非常简单,只要要调使用grunt对象的registerTask方法就可,其中第一个参数是Task的名称,第二个参数是回调函数使用来存放具体的任务(比方这里是打印输出)。

在自己设置任务中,我们使用到了grunt.log.writeln函数,这是Grunt提供的众多内置方法之一,作使用是向控制台输出消息并换行。同类型的方法还有grunt.log.error()、grunt.log.subhead()等方法,大家可以到官网API文档自行查看。

Grunt项目在具体用的时候,通常是自己设置Task + Grunt插件相结合的形式,我们来看下面这段代码:

//包装函数
module.exports = function (grunt) {
//(1)自己设置任务(一) 任务名称 hello
grunt.registerTask("hello",function () {
grunt.log.writeln("hello 文顶顶");
});
//(2)自己设置任务(二) 任务名称 football
grunt.registerTask("football",function () {
grunt.log.writeln("皇家马德里: how are you!");
grunt.log.writeln("尤文图斯: how old are you!");
});
//(2) 插件的解决
//用步骤:
//[1] 先把对应的插件下载和安装到本地的项目中 $ npm install grunt-contrib-concat --save-dev
//[2] 对插件(任务)进行配置 grunt.initConfig
//[3] 加载对应的插件 loadNpmTasks
//[4] 注册任务 grunt.registerTask
//[5] 通过grunt命令执行任务
//配置插件相关信息
grunt.initConfig({
"concat":{
"dist":{
"src":["src/demo_one.js","src/demo_two.js","src/demo_three.js"],
"dest":"dist/index.js"
}
}
});
//加载插件
grunt.loadNpmTasks("grunt-contrib-concat");
//注册任务(一):把hello \ football \ concat 这三个Task注册为default的Task
//当执行$ grunt 或者者是$ grunt default的时候,会顺序执行者三个任务!
grunt.registerTask("default",["hello","football","concat"]);
//注册任务(二)
grunt.registerTask("customTask",["hello","football"]);
};

对于上面的Gruntfile文件,假如在终端输入$ grunt或者者$ grunt default 命令则依次执行hello football和concat三个任务,输入$ grunt customTask则一次执行hello football 自己设置任务。

3.2 任务形容和依赖

设置任务形容

随着项目复杂性的添加,Grunt任务也会越来越多,而任务(Task)的可使用性、使用途以及调使用方法可能会变得难以追踪。所幸,我们可以通过给任务设定相应的形容信息来处理这些问题。

要给任务设置形容信息非常简单,只要要在调使用registerTask方法的时候多传递一个参数就可(作为第二个参数传递),我们可以把一个具体的字符串形容信息作为函数的参数传递。

这里,我们修改上面示例代码中football任务部分的代码,并任务设置形容信息。

grunt.registerTask("football","17-18赛季 欧冠八分之一决赛抽签场景",function () {
grunt.log.writeln("皇家马德里: how are you!");
grunt.log.writeln("尤文图斯: how old are you!");
});

此时,在终端中输入$ grunt --help命令就能够看到当前Grunt项目中可使用的Task,以及相应的形容信息了,关键信息如下。

Available tasks
hello Custom task.
football 17-18赛季 欧冠八分之一决赛抽签场景
concat Concatenate files. *
default Alias for "hello", "football", "concat" tasks.
customTask Alias for "hello", "football" tasks.

任务依赖

在复杂的Grunt工作流程中,很多任务之间往往存在依赖关系,比方js代码的语法检查和压缩这两个任务,压缩任务需要依赖于语法检查任务,它们在执行的时候存在肯定的先后关系,这种情况我们称之为任务依赖。

我们可以在注册任务的时候,刻意指定这种依赖关系,他们更多的是以一种特定的先后顺序执行。假如是自己设置任务,也可以通过grunt.task.requires()方法来设定这种任务间的依赖关系。

module.exports = function (grunt) {
//注册两个自己设置任务
/*
* 第一个参数:Task的名称
* 第二个参数:任务的形容信息
* */
grunt.registerTask("hi","形容信息:这是一个打招呼的任务",function () {
grunt.log.ok("hi 文顶顶");
});
grunt.registerTask("hello","任务的形容次信息:这是一个简单问候任务",function () {
//设置任务依赖:表明当前的任务在执行的时候需要依赖于另外一个任务
//必需先执行hi这个任务,才能执行hello这个任务
grunt.task.requires("hi");
console.log("Nice to meet you!");
});
};

上面的代码中定义了hi和hello两个任务,其中hello这个Task需要依赖于hi的执行,假如直接执行hello,那么会打印任务依赖的提醒信息,具体的执行情况如下。

wendingding:05-Grunt项目任务的形容和依赖 wendingding$ grunt hello
Running "hello" task
Warning: Required task "hi" must be run first. Use --force to continue.
Aborted due to warnings.
wendingding:05-Grunt项目任务的形容和依赖 wendingding$ grunt hi hello
Running "hi" task
>> hi 文顶顶
Running "hello" task
Nice to meet you!
Done.

3.3 Grunt多目标任务和Options选项

了解多目标Task

Grunt中的多目标任务(multi-task)是相对于基本任务而言的,多目标任务几乎是Grunt中最复杂的概念。它的用方式非常灵活,其设计的目的是可以在当个项目中支持多个Targets目标[可以认为是多种配置]。当任务在执行的时候,可以一次性执行一律的Target也可以指定某一特定的Target执行。

module.exports = function (grunt) {
//(1) 配置Task,给Task设置多个Target
grunt.config("hello",
{
"targetA":{
"des":"Nice to meet you!"
},
"targetB":{
"des":"how are you?"
},
}
);
//(2) 自己设置任务 任务的名称为hello
//第一个参数:Task名称
//第二个参数:任务的形容信息
//第三个参数:具体要执行的任务
grunt.registerMultiTask("hello","形容信息:打招呼",function () {
grunt.log.ok("hello 文顶顶");
grunt.log.writeln("this.target:",this.target);
grunt.log.writeln("this.data:",this.data);
});
};

代码说明

通过观察可以发现,我们通过grunt.registerMultiTask方法创立了支持多任务(Target)操作的自己设置任务hello,主要任务就是输出“hello 文顶顶”消息以及打印当前的target和data值。而后通过grunt.config方法来给hello这个Task设定了两个Target,分别是targetA和targetB。

在上面的代码中,我们引使用了this.target和this.data这两个属性,回调函数中的this指向的是当前正在运行的目标对象。执行targetA这个选项的时候,打印的this对象如下:

{ nameArgs: 'hello:targetA',
name: 'hello',
args: [],
flags: {},
async: [Function],
errorCount: [Getter],
requires: [Function: bound ],
requiresConfig: [Function],
options: [Function],
target: 'targetA',
data: { des: 'Nice to meet you!' },
files: [],
filesSrc: [Getter] }

目前为止,我们一直在谈论Task(任务)和Target(目标),大家可能懵逼了,不禁要问它们之间究竟是什么关系?

私以为可以简单的类比一下,假设现在有一个任务就是中午吃大餐,而具体吃什么大餐,可以灵活安排多个方案进行选择,比方方案A吃西餐,方案B吃中餐,方案C吃日本料理。等我们真正到了餐馆要开吃的时候,可以选择方案A吃西餐或者者是方案B吃中餐,甚至中餐、西餐和日本料理全端上桌也未尝不可。

Task指的是整个任务,在这个例子中就是要吃大餐,Target指的是任务中的某一种可行方案,也就是方案A、方案B和方案C,吃大餐这个Task中我们配置了三个Target。定义任务的目的是为了执行,在执行Task的时候,我们可以选择执行某个或者某几个指定的Target(目标),这样的解决方式无疑更强大而且操作起来更加的灵活。

多目标任务的执行

运行多目标Task的时候,有多种方式选择。

① 让Task按照指定的target运行。$ grunt TaskName:targetName

② 让Task把所有的target都运行一次。$ grunt TaskName

下面列出示例代码的具体执行情况

wendingding:05-Grunt项目任务的形容和依赖 wendingding$ grunt hello
Running "hello:targetA" (hello) task
>> hello 文顶顶
this.target: targetA
this.data: { des: 'Nice to meet you!' }
Running "hello:targetB" (hello) task
>> hello 文顶顶
this.target: targetB
this.data: { des: 'how are you?' }
Done.
wendingding:05-Grunt项目任务的形容和依赖 wendingding$ grunt hello:targetA
Running "hello:targetA" (hello) task
>> hello 文顶顶
this.target: targetA
this.data: { des: 'Nice to meet you!' }
Done.
wendingding:05-Grunt项目任务的形容和依赖 wendingding$ grunt hello:targetB
Running "hello:targetB" (hello) task
>> hello 文顶顶
this.target: targetB
this.data: { des: 'how are you?' }
Done.

假如在Gruntfile文件中,调使用了grunt.registerTask方法来注册自己设置任务,那么可以通过TaskName:targetName的来方式直接指定任务的Target

//注册任务 [给hello起一个别名]
grunt.registerTask("helloTargetA",["hello:targetA"]);

在终端中,输入$ grunt helloTargetA命令将会执行hello这个Task中的targetA选项。

多目标任务的Options选项

在对多目标的任务进行配置的时候,任何存储在options选项下面的数据都会被特殊的解决。

下面列出一份Gruntfile文件中的核心代码,并以多种方式执行,通过这份代码能够帮助我们了解多目标任务的Options选项配置。

//包装函数
module.exports = function (grunt) {
//(1) 配置Task相关信息
/*
* 第一个参数:Task的名称
* 第二个参数:任务的形容信息
* */
grunt.initConfig({
"hi": {
/*对整个任务中所有target的配置项 全局配置*/
options:{
"outPut":"array"
},
targetA:{
arrM:["targetA_1","targetA_2","targetA_3"]
},
targetB:{
options:{
"outPut":"json"
},
arrM:["targetB_1","targetB_2","targetB_3"]
},
targetC:{
arrM:["targetC_1","targetC_2","targetC_3"]
}
}
});
//(2) 自己设置任务 Task名称为hi
//第一个参数:Task名称
//第二个参数:任务的形容信息
//第三个参数:具体要执行的任务
grunt.registerMultiTask("hi","形容次信息:这是一个打招呼的任务",function () {
console.log("任务当前执行的target: "+this.target);
console.log("任务当前执行的target对应的数据: \n");
var objT = this.options();
if (objT.outPut === "array")
{
console.log("输出数组:\n");
console.log(this.data.arrM);
}else if (objT.outPut === "json")
{
console.log("输出JSON数据:\n");
console.log(JSON.stringify(this.data.arrM));
}
});
//(1) 相关的概念 Task(任务-hi) | target(目标)
//(2) 任务的配置:任务中可以配置一个或者者是多个目标 调使用config
//(3) 复合任务的执行(多任务-多target)
// 001 grunt TaskName 把当前Task下面所有的目标操作都执行一遍
// 002 grunt TaskName:targetName 执行当前Task下面的某一个指定的目标
grunt.registerTask("default",["hi"]);
};

具体的执行情况

wendingding:06-Grunt项目多任务和options wendingding$ grunt
Running "hi:targetA" (hi) task
任务当前执行的target: targetA
任务当前执行的target对应的数据:
输出数组:
[ 'targetA_1', 'targetA_2', 'targetA_3' ]
Running "hi:targetB" (hi) task
任务当前执行的target: targetB
任务当前执行的target对应的数据:
输出JSON数据:
["targetB_1","targetB_2","targetB_3"]
Running "hi:targetC" (hi) task
任务当前执行的target: targetC
任务当前执行的target对应的数据:
输出数组:
[ 'targetC_1', 'targetC_2', 'targetC_3' ]
Done

代码说明

上面的代码中定义了一个多目标任务,Task的名称为hi,该Task有三个target目标选项,分别是targetA、targetB和targetC。在任务配置相关代码中,全局的options配置项中outPut属性对应的值为array,表示具体的目标任务在执行的时候以数组的形式输出。

我们看到在targetB目标中重写了options选项中的outPut属性为json,当终端执行$ grunt命令的时候,会依次执行所有三个target目标选项,而targetA和targetC以数组格式来输出内容,targetB则以json格式来输出内容。

Grunt多目标任务以及选项使得我们可以针对不同的应使用环境,以不同的方式来运行同一个Task。可以利使用这一点,我们完全能够定义Task为不同的构建环境创立不同的输出目标。

说明 ? this.options()方法使用于获取当前正在执行的目标Task的options配置选项

3.4 Grunt项目任务配置模板

Grunt项目中配置模板的简单用

在Grunt项目中,我们可以用<% %>分隔符的方式来指定模板,当Task读取自己配置信息的时候模板的具体内容会自动扩展,且支持以递归的方式开展。

在通过<%= ... %>在向模板绑定数据的时候,我们可以直接传递配置对象中的属性或者调使用grunt提供的方法,模板中属性的上下文就是当前的配置对象。

下面,我们通过Gruntfile文件中的一段核心代码来展示配置模板的用情况。

module.exports = function (grunt) {
//(1) 创立并设置grunt的配置对象
//配置对象:该对象将作为参数传递给grunt.config.init方法
var configObj = {
concat: {
target: {
//src:["src/demo1.js","src/demo2.js"]
src: ['<%= srcPath %>demo1.js', '<%= srcPath %>demo2.js'],
//dest:["dist/2018_05_21_index.js"]
dest: '<%= targetPath %>',
},
},
srcPath:"src/",
destPath:"dist/",
targetPath:"<%= destPath %><%= grunt.template.today('yyyy_mm_dd_') %>index.js"
};
//(2) 调使用init方法对任务(Task)进行配置
// grunt.config.init 方法 === grunt.initConfig方法
grunt.config.init(configObj);
//(3) 加载concat插件
grunt.loadNpmTasks("grunt-contrib-concat");
//(4) 注册Task
grunt.registerTask("default",["concat"]);
};

上面这段代码对concat插件代码合并Task进行了配置,用到了模板技术。该任务把src目录下的demo1和demo2两个js文件合并到dist目录下并命名为2018_05_21_index.js文件。

Grunt项目中导入外部的数据

在向模板绑定数据的时候,常见的做法还会导入外部的数据,并把导入的数据设置为配置对象的指定属性值。比方在开发中常常需要使用到当前Grunt项目的元信息,包括名称、版本等,这些数据常通过调使用grunt.file.readJSON方法加载package.json文件的方式获取。下面给出代码示例:

//包装函数
module.exports = function (grunt) {
//设置(demoTask和concat)Task的配置信息
grunt.config.init({
//从package.json文件中读取项目的元(基本)信息
pkg:grunt.file.readJSON("package.json"),
//demoTask的配置信息
demoTask :{
banner:"<%=pkg.name%> -- <%=pkg.version%>"
},
//concat的配置信息
concat:{
options:{
stripBanners:true,
banner:'/*项目名称:<%=pkg.name%> 项目版本:<%=pkg.version%> 项目的作者:<%=pkg.author%> 升级时间:<%=grunt.template.today("yyyy-mm-dd")%>*/\n'
},
target:{
src:["src/demo1.js","src/demo2.js"],
dest:'dist/index.js'
}
}
});
//自己设置Task 任务的名称为demoTask
grunt.registerMultiTask("demoTask",function () {
console.log("执行demo任务");
//表示调使用config方法来读取demoTask里面的banner属性并输出
console.log(grunt.config("demoTask.banner"));
});
//从node_modules目录中加载concat插件
//注意:需要先把插件下载到本地 npm install grunt-contrib-concat --save-dev
grunt.loadNpmTasks("grunt-contrib-concat");
//注册任务
grunt.registerTask("default",["demoTask","concat"]);
};

假如在终端输入$ grunt命令执行,那么demoTask任务将会输出grunt_demo -- 1.0.0打印消息,而concat任务则把两个js文件合并到dist目录下面的index.js文件并增加注释信息。

wendingding$ grunt
Running "demoTask:banner" (demoTask) task
执行demo任务
grunt_demo -- 1.0.0
Running "concat:target" (concat) task
Done.
wendingding:07-Grunt项目模板配置 wendingding$ cat dist/index.js
/*项目名称:grunt_demo 项目版本:1.0.0 项目的作者:文顶顶 升级时间:2018-05-21*/
console.log("demo1");
console.log("demo2");

说明 grunt.file.readJSON方法使用于加载JSON数据,grunt.file.readYAML方法使用于加载YAML数据。

3.5 Grunt自动化构建和监听

到这里,基本上即可以说已经熟练掌握Grunt了。上文我们在进行代码演示的时候,不管是自己设置任务还是Grunt插件用的讲解都是片段性的,支离破碎的,Grunt作为一款自动化构建工具,自动化这三个字到现在还没有表现出来。

顾名思义,自动化构建的意思就是能够监听项目中指定的文件,当这些文件发生改变后自动的来执行某些特定的任务。 否则的话,每次修改文件后,都需要我们在终端里面输入对应的命令来重新执行,这顶多能算半自动化是远远不够的。

下面给出一份更全面些的Gruntfile文件,该文件中用了几款常使用的Grunt插件(uglify、cssmin、concat等)来搭建自动化构建项目的工作流。点击获取演示代码

//包装函数
module.exports = function (grunt) {
// 项目配置信息
grunt.config.init({
pkg:grunt.file.readJSON("package.json"),
//代码合并
concat:{
options:{
stripBanners:true,
banner:'/*项目名称:<%=pkg.name%> 项目版本:<%=pkg.version%> 项目的作者:<%=pkg.author%>'
+' 升级时间:<%=grunt.template.today("yyyy-mm-dd")%>*/\n'
},
target:{
src:["src/demo1.js","src/demo2.js"],
dest:'dist/index.js'
}
},
//js代码压缩
uglify:{
target:{
src:"dist/index.js",
dest:"dist/index.min.js"
}
},
//css代码压缩
cssmin:{
target:{
src:"src/index.css",
dest:"dist/index.min.css"
}
},
//js语法检查
jshint:{
target:['Gruntfile.js',"dist/index.js"],
options:{
jshintrc:".jshintrc"
}
},
//监听 自动构建
watch:{
target:{
files:["src/*.js","src/*.css"],
//只需指定路径的文件(js和css)发生了变化,就自动执行tasks中列出的任务
tasks:["concat","jshint","uglify","cssmin"]
}
}
});
//通过命令行安装插件(省略...)
//从node_modules路径加载插件
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-watch");
//注册任务:在执行$ grunt命令的时候依次执行代码的合并|检查|压缩等任务并开启监听
grunt.registerTask("default",["concat","jshint","uglify","cssmin","watch"])
};

当在终端输入$ grunt命令的时候,grunt会执行以下任务

① 合并src/demo1.js和src/demo2.js文件并命名为index.js保存到dist目录

② 按照既定的规则对Gruntfile.js和index.js文件来进行语法检查

③ 压缩index.js文件并命名为index.min.js保存在dist目录

④ 压缩src/index.css文件并保存到dist/index.min.css

⑤ 开启监听,假如src目录下面的js文件或者css文件被更改则重新构建

作者:叩丁狼教育前台学科-杨勇老师

  • 全部评论(0)
最新发布的资讯信息
【系统环境|】Hadoop环境中管理大数据存储八大技巧(2019-06-15 11:01)
【系统环境|服务器应用】现在国内IT行业是不是程序员过多了?(2019-06-11 06:34)
【系统环境|服务器应用】新贵 Flutter(2) 自己设置 Widget(2019-06-11 06:34)
【系统环境|服务器应用】Android完整知识体系路线(菜鸟-资深-大牛必进之路)(2019-06-11 06:34)
【系统环境|服务器应用】Java程序员小伙经历三个月备战,终获阿里offer(2019-06-11 06:34)
【系统环境|服务器应用】每日一问:谈谈对 MeasureSpec 的了解(2019-06-11 06:34)
【系统环境|服务器应用】【科普】晶体管-1(2019-06-11 06:34)
【系统环境|服务器应用】一个很多人都会答错的java基础题(2019-06-11 06:33)
【系统环境|服务器应用】深入了解枚举类型(2019-06-11 06:33)
【系统环境|服务器应用】JavaScript编译原理与内存管理(2019-06-11 06:33)
手机二维码手机访问领取大礼包
返回顶部