《JavaScript开发框架权威指南》——2.2 Grunt是如何工作的

2.2 Grunt是如何工作的

Grunt为开发者提供了一个工具包,用于创建命令行程序来执行项目构建过程中的重复性任务,如压缩JavaScript代码、编译Sass样式表等。不过,Grunt的能力并不限于创建简单的任务(通常这些任务不会被分享或者复用),以解决特定工程遇到的特定需求,其真正的力量源于其将任务打包为可复用的插件的能力。这些插件可以被发布、分享、使用以及由其他人进行改进。本书写作之时已经有超过4 400个这样的插件。

Grunt的运转依赖于四个核心组件,接下来逐一论述。

2.2.1 Gruntfile.js
在Grunt中处于核心地位的是Gruntfile——一个位于工程根目录下的名为Gruntfile.js(见清单)的Node模块。正是这个文件使得我们可以加载Grunt插件,创建自定义任务,并根据项目需求对它们进行配置。Grunt每次运行时的首要任务都是接受该模块发出的指令。

清单2-2 Gruntfile示例

// example-starter/Gruntfile.js

module.exports = function(grunt) {

    /**
     * 配置即将用到的任务和插件
     */
    grunt.initConfig({
        /* Grunt的file API为开发者提供了与文件系统进行交互所必需的抽象。稍后,我们将在
        本章对此进行深入了解。*/
        'pkg': grunt.file.readJSON('package.json'),
        'uglify': {
            'development': {
                'files': {
                    'build/app.min.js': ['src/app.js', 'src/lib.js']
                }
            }
        }
    });
    /**
    * Grunt插件以Node包的形式存在,并由npm发布。这里,我们加载的是grunt-contrib-uglify插件。
    * 该插件包含的任务可以对项目源代码进行合并与压缩,以备发布之用。
    */
    grunt.loadNpmTasks('grunt-contrib-uglify');

    /**
     * 这里,我们创建了一个名为default的任务,其仅有的功能就是调用uglify任务。换句话说,该任务
     * 实际上是uglify任务的别名。名为default的任务指明了在命令行中不带参数调用Grunt时应当执
     * 行的动作。在本例中,我们的default任务仅仅调用了一个单独的任务。不过(依次)调用多个任务
     * 其实同样简单,只要在传入的数组中添加多个条目即可。
     */
    grunt.registerTask('default', ['uglify']);

    /**
     * 这里,我们创建了一个自定义任务,利用Grunt内置的用户反馈(user feedback)方法,向控制台
     * 输出一条消息(后面还有一个换行符)。稍后,我们将在本章对此做深入了解。
     */
    grunt.registerTask('hello-world', function() {
        grunt.log.writeln('Hello, world.');
    });
};

2.2.2 任务(Tasks)
作为Grunt的基本构建模块,任务实际上只是由Grunt的registerTask()方法注册的具名函数。清单所示的hello-world任务将向控制台输出一条消息。在命令行中调用该任务的结果,如清单所示。

清单2-3 运行清单中所示的hello-world任务

$ grunt hello-world
Running "hello-world" task
Hello, world.

Done, without errors.

如清单所示,多个Grunt任务也可以由单条命令调用执行。每个任务都将按照参数的传入顺序依次执行。

清单2-4 顺序运行多个任务

$ grunt hello-world uglify
Running "hello-world" task
Hello, world.

Running "uglify:development" (uglify) task
>> 1 file created.

Done, without errors.

我们刚看到的hello-world任务是简单独立型Grunt任务的代表。这样的任务可以用于实现一些简单的功能,以解决特定项目的需求。通常我们不会考虑其复用或者分享的问题。但是多数时候,你会发现我们实际用到的都不是这样的独立型任务,而是那些已经打包为Grunt插件并发布到npm的任务。以插件的形式发布更便于别人使用或者参与改进。

2.2.3 插件(Plugins)
Grunt插件是一系列能够用于不同项目的可配置任务(以npm包的形式发布)的集合。现存的Grunt插件数以千计,可谓洋洋大观。清单中的Grunt方法loadNpmTasks()用以加载名为grunt-contrib-uglify的Node模块。该模块可以将工程中的JavaScript代码合并为单个压缩(minified)文件,以适应发布需求。

2.2.4 配置
Grunt以强调“配置优先”(configuration over code)而著称:任务和插件的功能均可通过配置文件进行定制,以适应不同工程的需求。正是这种代码与配置分离的特性,使开发者能够创造出容易被复用的插件。本章稍后将介绍配置Grunt插件和任务的各种不同的方法。

时间: 2024-10-02 12:03:18

《JavaScript开发框架权威指南》——2.2 Grunt是如何工作的的相关文章

《JavaScript开发框架权威指南》——第2章 Grunt 2.1安装Grunt

第2章 Grunt 我是一个懒人.但正是懒人发明了轮子和自行车,因为他们既不愿意走路,也不愿意负重前行. --莱赫·瓦文萨,波兰前总统 拉里·沃尔(Larry Wall,著名的Perl语言创始人)在他的<Programming Perl>一书中提到,所有成功的程序员都有三个重要的品质:懒惰.急躁以及狂妄.乍一看,这些都是相当糟糕的品质,但是只是深挖一下,你就会发现其言外之意. 懒惰:懒惰的程序员讨厌重复自己.他们通常会花费大量的时间去创造有用的工具,代替自己完成重复性的工作.他们往往还会为这些

《JavaScript开发框架权威指南》——2.6 创建Grunt插件

2.6 创建Grunt插件 社区提供的丰富插件库是让Grunt真正变得闪耀的库,它能使你立即从Grunt中获益,而不是需要从头创建复杂的任务.如果你需要在项目中做自动构建,那么很可能某人已经为你做好这项"Grunt"工作.在这一节中,你可以懂得如何向社区回馈自己创建的Grunt插件. 2.6.1 开始 首先要做的事情之一是情创建一个公共的GitHub仓库,以存储你的新插件.下文中将要提及的示例包含在本书附带的源码中,本书附带了源码.一旦你准备好代码仓库,就把它克隆到你的电脑上.下一步,

《JavaScript开发框架权威指南》——2.3 将Grunt添加到项目中

2.3 将Grunt添加到项目中 在本章前面,为了添加Grunt命令行工具,我们将npm包grunt-cli作为全局模块进行了安装.现在我们应该已经可以在命令行中使用Grunt命令,但是对于每个要使用Grunt的工程,仍然需要为其配置Grunt本地依赖.为此,只需在工程根目录下运行以下命令即可.本例假设npm已经针对示例所用项目进行了初始化,package.json文件也已经存在. $ npm install grunt --save-dev 现在,我们项目的package.json文件应该已经

《JavaScript开发框架权威指南》——2.5 操作文件系统

2.5 操作文件系统 可想而知,作为构建工具,大部分Grunt插件都要以某种方式和文件系统交互.鉴于操作文件的重要性,Grunt提供了有益的抽象允许开发者与文件系统交互,并且仅仅使用很少数量的样板代码. 当然,我们不会把所有方法都列举在此,表显示了Grunt文件操作API中一些使用频率最高的方法.2.5.1 源-目标映射 许多Grunt任务与文件系统交互是依赖于源-目标映射的,该映射描述了要被处理的文件及各文件对应的目标.构建这样的映射会很冗长乏味,感谢Grunt为我们提供了解决此问题的有益捷径

《JavaScript开发框架权威指南》——2.4 处理任务

2.4 处理任务 对于配置来说,Grunt的config()方法既是"getter",也是"setter".在清单中,我们可以看到一个基本的Grunt任务是如何通过此方法来存取配置的. 清单2-9 管理一个基本Grunt任务的配置 module.exports = function(grunt) { grunt.config('basic-task', { 'message': 'Hello, world.' }); grunt.registerTask('basi

《JavaScript开发框架权威指南》——第1章 Bower 1.1准备工作

第1章 Bower 九层之台,起于累土. -- 文森特·梵高 包管理(Package Management),又作依赖关系管理(Dependency Management),并不是什么新奇的概念.此类工具为开发者提供了一种机制,以管理软件项目所依赖的各种第三方库.一些得到广泛应用的例子有: npm:Node.js的包管理工具: Composer:一种PHP依赖关系管理工具: pip:PyPA的推荐工具,用于安装Python包: NuGet:包括.NET在内的微软开发平台的包管理工具. 尽管包管理

《JavaScript开发框架权威指南》——2.7 小结

2.7 小结 本章中,我们学习了功能强大的Grunt套件,让开发者对重复.枯燥冗长的任务进行自动化处理,还展示了: Grunt的工作原理(任务.插件和配置对象). 如何配置任务和插件. 如何利用Grunt内置的很多实用工具为用户提供反馈信息.与文件系统交互. 如何创建和分享你自己的插件.

《JavaScript开发框架权威指南》——1.6 维护依赖链

1.6 维护依赖链 Bower给开发者带来的一个主要好处,就是可以非常方便地对整个项目的依赖链以一种相对受控的方式进行集中升级.为此,我们先来看一下本章示例项目所包含的依赖项列表(见清单). 清单1-8 安装并列出示例项目所需的Bower包 $ bower install bower bootstrap#3.2.0 cached git://github.com/twbs/bootstrap.git#3.2.0 bower bootstrap#3.2.0 validate 3.2.0 again

《JavaScript开发框架权威指南》——1.5 语义化版本控制

1.5 语义化版本控制 如果安装了jQuery(见清单),那么请查看项目的Bower清单.你所看到的应当与清单相仿. 清单1-7 语义化版本号 "dependencies": { "jquery": "~2.1.3" } 清单中的版本号2.1.3(请暂时忽略-)就是所谓的语义化版本号(Semver,Semantic Version).语义化版本控制能够帮助开发者按照通用格式为其项目指定版本号.该格式如下所示. Version X.Y.Z(Majo