程序员开发实例大全宝库

网站首页 > 编程文章 正文

Grunt高级使用(grub使用方法)

zazugpt 2024-08-27 23:52:01 编程文章 18 ℃ 0 评论

一,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作为项目构建工具的时候,所做的事情大概可以分成三块:准备、配置、执行。

① 准备阶段

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

? 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文件被更改则重新构建

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

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表