剖析Grunt任务配置

之前博客中大致描述过“前端自动化构建工具Grunt”及“grunt[mismatched:define]”等信息。然而,并没有深入;下述内容,将深入剖析Grunt Files处理方式、配置项、自定义插件。

一、准备工作

A. 通过npm init在项目根目录下生成package.json

B. 通过npm install grunt --save-dev 安装grunt依赖;

C. 项目根目录下手动创建文件夹Gruntfile.js

Gruntfile由以下几部分构成:

① “wrapper” 函数

② 项目与任务配置

③ 加载grunt插件和任务

④ 自定义任务

1. Wrapper函数

每一个Gruntfile文件遵循同样的格式,所有代码必须包裹在下述函数中:

module.exports = function(grunt){
    // grunt相关其他信息
};

2. 项目与任务配置

Grunt的task配置都是在 Gruntfile 中的grunt.initConfig方法中指定的。

grunt.initConfig({
    copy: {}
});

3. 加载Grunt插件和任务

只要在 package.json 文件中被列为dependency(依赖)的包,并通过npm install安装之后,都可以在Gruntfile中以简单命令的形式使用:

// 加载能够提供"copy"任务的插件。
grunt.loadNpmTasks(‘grunt-contrib-copy‘);

可以通过“load-grunt-tasks”进行一次性载入所有插件,无需依依引入。

require(‘load-grunt-tasks‘)(grunt);

4. 自定义任务

(1)自定义任务

grunt.registerTask(taskName, [description, ] taskList)
grunt.registerMultiTask(taskName, [description, ] taskFunction)

示例:

grunt.registerTask(‘cunstom-copy‘, [‘copy:js‘]);
grunt.registerMultiTask(‘default‘, [‘clean‘, ‘copy‘]);

注意:但是其自定义name(“cunstom-copy”)不能为上述“原子”任务名称,否则会造成死循环!导致“Maximum call stack size exceeded”问题!

(2)基本任务

执行指定的任务函数,并传递任何使用冒号分割的参数作为函数的参数。

grunt.registerTask(taskName, [description, ] taskFunction)

示例

grunt.registerTask(‘foo‘, ‘A sample task that logs stuff.‘, function(arg1, arg2) {
    grunt.log.writeln(arg1 + "," + arg2);
    // 内部通过run执行其他任务
    grunt.task.run(‘bar‘, ‘baz‘);
});

二、配置任务

grunt.initConfig方法中指定任务配置,主要是以任务名称命名的属性,也可以包含其他任意数据。在grunt.initConfig({})中不针对任何Task的属性,Grunt会将作为常量进行储存,以备后续通过<%= %>引用。

module.exports = function(grunt){
    var config = {
        app: ‘app‘,  // 源文件目录
        dest: ‘dest‘ // 目标文件目录
    };
    grunt.initConfig({
        config: config,
        pkg: grunt.file.readJSON(‘package.json‘),

        copy: {
            js: {
                expand: true,
                cwd: ‘<%= config.app %>/‘,
                src: [‘js/**/*.js‘],
                dest: ‘<%= config.dest %>/dest/‘
            }
        }
    });

    // 加载插件
    grunt.loadNpmTasks(‘grunt-contrib-copy‘)
};
  • config和pkg为常量,其中config在文件开头处定义方便统一,便于后续修改。
  • copy为Task,加载“grunt-contrib-copy”插件
  • copy中的js为Target,可以通过grunt copy:js执行

通配符说明:

通配符 说明
* 匹配任意数量的字符,但不匹配 /
? 匹配单个字符,但不匹配 /
** 匹配任意数量的字符,包括 /,只要它是路径中唯一的一部分
{} 允许使用一个逗号分割的“或”表达式列表
! 在模式的开头用于排除一个匹配模式所匹配的任何文件

A. foo/*.js将匹配位于foo/目录下的所有的.js结尾的文件;

B. foo/**/*js将匹配foo/目录以及其子目录中所有以.js结尾的文件。

模板说明:

使用<%= %>分隔符指定的模板会在任务从它们的配置中读取相应的数据时将自动扩展扫描。在模板中使用grunt以及它的方法都是有效的,例如: <%= grunt.template.today(‘yyyy-mm-dd‘) %>

1. 任务配置和目标

当运行一个任务时,Grunt会自动查找配置对象中的同名属性。

grunt copy会自动匹配initConfig()方法中的copy属性,在不指定target情况下,默认将遍历所有目标(target)并依次处理。也可以同时指定任务(task)和目标(target),grunt copy:js 将只会处理指定目标(target)的配置。

2. options属性

在一个任务配置中,options属性可以用来指定覆盖内置属性的默认值。此外,每一个目标(target)中还可以拥有一个专门针对此目标(target)的options属性。注意,options对象是可选的,如果不需要,可以忽略。

grunt.initConfig({
  concat: {
    options: {
      // 这里是任务级的Options,覆盖默认值
    },
    foo: {
      options: {
        // "foo" target options may go here, overriding task-level options.
      },
    },
    bar: {
      // No options specified; this target will use task-level options.
    },
  },
});

3. 文件

由于大多的任务都是执行文件操作,Grunt有一个强大的抽象层用于声明任务应该操作哪些文件。

(1)简洁格式

每个目标对应一个src-dest文件映射

copy: {
    js: {
        src: [‘<%= config.app %>/js/**/*.js‘],
        dest: ‘<%= config.dest %>/‘
    },
    html: {
        src: ‘<%= config.app %>/html/**/*.html‘,
        dest: ‘<%= config.dest %>/‘
    }
}

(2)文件对象格式

每个目标对应多个src-dest形式的文件映射,属性名就是目标文件,源文件就是它的值(源文件列表则使用数组格式声明)。

copy: {
    ‘<%= config.dest %>/‘: [‘<%= config.app %>/js/**/*.js‘, ‘<%= config.app %>/html/**/*.html‘]
}

(3)文件数组格式

每个目标对应多个src-dest文件映射

copy: {
    bulid: {
        files: [{ src: [‘<%= config.app %>/js/**/*.js‘], dest: ‘<%= config.dest %>/‘},
            { src: ‘<%= config.app %>/html/**/*.html‘, dest: ‘<%= config.dest %>/‘}]
    }
}

简洁格式”和“文件数组格式”可以支持下列属性:

属性 说明
filter 它通过接受任意一个有效的fs.Stats方法名或者一个函数来匹配src文件路径并根据匹配结果返回true或者false
nonull 如果被设置为true,未匹配的模式也将执行。结合Grunt的–verbore标志, 这个选项可以帮助用来调试文件路径的问题
dot 它允许模式模式匹配句点开头的文件名,即使模式并不明确文件名开头部分是否有句点
matchBase 如果设置这个属性,缺少斜线的模式(意味着模式中不能使用斜线进行文件路径的匹配)将不会匹配包含在斜线中的文件名。 例如,a?b将匹配/xyz/123/acb但不匹配/xyz/acb/123
expand 处理动态的src-dest文件映射

示例:filter

clean: {
    foo: {
        src: [‘tmp/**/*‘],
        filter: ‘isFile‘,
    },
    bar: {
        src: [‘tmp/**/*‘],
        filter: function(filepath) {
            return (grunt.file.isDir(filepath)
            && require(‘fs‘).readdirSync(filepath).length === 0);
          },
    }
}

其中isFile为fs.Stats中的方法,可以直接引用!当然,也可以自定义filter,其函数第一个参数为当前文件路径,上述自定义函数为清空空文件夹

当你希望处理大量的单个文件时,可以通过一些附加的属性来动态的构建一个文件列表。前提,expand 设置为true:

属性 说明
cwd 所有src指定的匹配都将相对于此处指定的路径(但不包括此路径)
src 相对于cwd路径的匹配模式
dest 目标文件路径前缀
ext 对于生成的dest路径中所有实际存在文件,均使用这个属性值替换扩展名
extDot 用于指定标记扩展名的英文点号的所在位置。可以赋值 ‘first’ (扩展名从文件名中的第一个英文点号开始) 或 ‘last’ (扩展名从最后一个英文点号开始),默认值为 ‘first’ [添加于 0.4.3 版本]
flatten 从生成的dest路径中移除所有的路径部分
rename 对每个匹配的src文件调用这个函数(在重命名后缀和移除路径之后)。dest和匹配的src路径将被作为参数传入,此函数应该返回一个新的dest值。 如果相同的dest返回不止一次,那么,每个返回此值的src来源都将被添加到一个数组中作为源列表

三、补充:

1. grunt支持异步等写法,请参考其API

2. 创建问题,请参考其常见问题

3. 可以通过插件“time-grunt”进行统计每个Task执行时间

require(‘time-grunt‘)(grunt);
时间: 2024-08-04 16:53:31

剖析Grunt任务配置的相关文章

Grunt安装配置教程:前端自动化工作流

Grunt这货是啥? Grunt 是一个基于任务的 JavaScript 项目命令行构建工具. 最近很火的前端自动化小工具,基于任务的命令行构建工具 http://gruntjs.com Grunt能帮我们干啥? 在开始介绍前,先向大家描述下面的场景: [场景1:项目开始前] 先建立一个 projA 的文件夹 再建 html css js images (建5个或以上文件夹,花费1分钟) 拷贝 CSS库(Yui Reset bootstrap)JS库(Requiet.js Seajs jQuer

Grunt的配置及使用(压缩合并js/css)

Grunt的配置及使用(压缩合并js/css) 安装 前提是你已经安装了nodejs和npm. 你能够在 nodejs.org 下载安装包安装.也能够通过包管理器(比方在 Mac 上用 homebrew,同一时候推荐在 Mac 上用 homebrew). 安装grunt CLI npm install -g grunt-cli 依照官方的说法.grunt-cli仅仅是为了在同一台机器上安装不同的grunt版本号,那么咱们先不去管他. 在项目中使用grunt 首先须要往项目里加入两个文件:pack

grunt基础配置

grunt基础配置 要使用grunt来管理项目,一般需要如下的几个步骤: 安装grunt命令行工具grunt-cli 在项目中安装grunt 安装grunt插件 建立并配置Gruntfile.js 安装grunt命令行工具 npm install -g grunt-cli 在项目中安装grunt npm install grunt --save-dev 安装完成后,可以在package.json文件中看到devDependencies中加入了grunt包 "devDependencies&quo

grunt安装配置

1.安装nodeJs环境(包含npm) 2.$ npm install -g grunt-cli //可调用与Gruntfile在同一目录中的Grunt版本 3-1.$ npm install -g grunt-init 大部分 grunt-init 模版都会自动创建特定于项目的package.json文件 3-2.$ npm init //命令会创建一个基本的package.json文件,一步步设置回车. C:\Users\***\AppData\Roaming\npm\node_module

STL源码剖析——空间的配置与释放

C++的内存配置基本操作是  ::operator new(),内存释放的基本操作是 ::operator delete().这两个全局函数相当于C的malloc()和free()函数.是的,正是如此,STL正是以malloc()和free()完成内存的配置与释放. 但是考虑到小型区块所可能造成的内存破碎问题,STL中设计了双层级配置器, 第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不用的策略:当配置区块超过128bytes时,视之为"足够大",便调用第

Grunt的配置和使用(一)

Grunt的配置和使用(一) Grunt 和 Grunt 的插件都是通过 Node.js 的包管理器 npm 来安装和管理的.为了方便使用 Grunt ,你应该在全局范围内安装 Grunt 的命令行接口(CLI).要做到这一点,你可能需要使用 sudo (OS X,*nix,BSD 等平台中)权限或者作为超级管理员( Windows 平台)来运行 shell 命令. npm install -g grunt-cli 使用全局安装之后,可以在任何一个目录中运行 grunt 命令. 如何工作 每次运

Web API 源码剖析之默认配置(HttpConfiguration)

我们在上一节讲述了全局配置和初始化.本节我们将就全局配置的Configuration只读属性进行展开,她是一个类型为HttpConfiguration. 它在Web Api 主要为整个API 做一些最基础的工作,比如定义默认 路由表(Routes) 过滤器(Filters) 默认消息处理程序(MessageHandlers) 属性字典(Properties) 依赖注入解耦器(DependencyResolver) 错误处理策略(IncludeErrorDetailPolicy) 服务(Servi

Web API 源码剖析之全局配置

Web API  均指Asp.net Web API .本节讲述的是基于Web API 系统在寄宿于IIS. 本节主要讲述Web API全局配置.它是如何优雅的实现这个配置.做过MVC 都知道Global文件来初始化.Web API 本质上也是ASP.NET applications.所以也是在Global定义里一个GlobalConfiguration静态类.该类作用就是初始化ASP.NET applications.如下是GlobalConfiguration的定义. //    // 摘要

《STL源码剖析》空间配置器

空间配置器(allocator) 空间配置器按我的理解就是C++ STL进行内存管理的组件(包括内存的申请和释放):当然,不只是内存,还可以向硬盘申请空间: 我主要看了内存的配置与释放(这里"配置"就应该是"申请"的意思).STL对此设计的哲学主要包括以下四个方面: 1.向系统堆空间申请内存空间 2.考虑了多线程的情况下的申请: 3.考虑内存不足的应变措施: 4.考虑过多"小型区块"的内存碎片的问题: C++ 申请的基本动作是::operator