grunt的插件机制

task.loadNpmTasks = function(name) {
  var root = path.resolve('node_modules');
  var tasksdir = path.join(root, packagename, 'tasks');   //加载grunt 插件的tasks
  if (grunt.file.exists(tasksdir)) {
  loadTasks(tasksdir);
  } else {
  grunt.log.error('Local Npm module "' + name + '" not found. Is it installed?');
  }
}

1、插件中使用插件

有时我们需要在插件中使用插件来充分利用package资源, 但是由于插件通常会再被其它package使用,tasksdir通常会定位到使用插件的package下的tasks; 所以就会报错找不到相关packageName的tasks。

那么我们可以通过在插件中重新定义 loadNpmTasks 方法来实现在当前package下加载插件, 如:

//grunt查找插件的规则是通过path.join(G)
var loadNpmTasks = function(name) {
var cwd = process.cwd();
var baseDir = path.resolve(__dirname, '..');
grunt.file.setBase(baseDir);
//packdir必须使用相对路径
grunt.loadNpmTasks(name);
grunt.file.setBase(cwd);
};

2、插件中文件的处理

可以通过 grunt.file.setBase(cwd) 来设计,文件操作的cwd

3、任务名称覆盖问题

如果在插件中使用到一些非常常用的第三方插件, 如grunt-contrib-clean、grunt-contrib-copy等插件,有可能在使用插件的package中也会用到, 所以一定不要覆盖使用插件的package的grunt配置,也不能merge配置, merge会导致执行顺序的修改。

举个例子:

grunt task build 的gruntfile

//package build
grunt.initConfig({
"build-xxx": {
//build-xxx是一个插件提供的task的配置
},
"clean": {
//使用插件 grunt-contrib-clean
}
}); //package build-xxx 中的tasks/build-xxx.js
grunt.registerTask('build-xxx', function() {
//如下会覆盖掉package build中的grunt config clean, 导致task clean不可用。
grunt.initConfig({
"clean": {},
"copy": {}
});
//merge会导致执行顺序被修改
grunt.config.merge({clean: {}}); grunt.task.run(["clean", "copy"])
});

以上两种方式都会导致用户在使用grunt插件时,得到和预期不一致的结果,但是一个好的插件是不应该让使用者关心下层的实现的, so,可以改进如下:

在build-xxx的tasks/build-xxx.js中增加一个cleanConfig的任务
var originGruntConfig = grunt.config.data;
grunt.initConfig({
"clean": {},
"copy": {},
"cleanConfig": {}
});
grunt.registerTask('cleanConfig', function() {
grunt.initConfig(originGruntConfig);
});

为什么要使用新增任务cleanConfig,而不是直接在 grunt.task.run(["clean", "copy"])  执行后将配置修改过来呢, 是因为grunt的run是基于任务队列运行, 不是及时同步完成。  我们需要在run结束后在将原有的config给同步过来。

4、task中的异步处理回调问题

如果在task的function body中存在异步调用,  这个问题和插件开发没什么关心,不过在用grunt写工具时需要注意一下

setTimeout(function() {
console.log('enter');
}, 2000);  

那么在grunt中是默认不会执行的, 原因grunt的tasks 队列运行机制, 队列中的tasks运行完之后会执行exit, 退出当前进程;

do {
thing = this._queue.shift();
} while (thing === this._placeholder || thing === this._marker);
// If queue was empty, we're all done.
if (!thing) {
this._running = false;
if (this._options.done) {
process.exit(0);
}
return;
}
}

可以使用grunt提供的 this.async()方法,  在异步回调结束后调用生成的done行数,已确保该异步调用能在下一个task之前执行, 如:

var done = this.async();
setTimeout(function() {
//do something;
done(true);
}, 2000);

grunt 插件开发注意事项的更多相关文章

  1. Grunt 插件开发与调式

    1 grunt是什么 官方网站解释的很清楚,http://gruntjs.com/ http://gruntjs.cn/ 它是一种javascript任务运行器,对于需要反复重复的任务,例如压缩.编译 ...

  2. cordova插件开发注意事项

    1. 编写插件,先创建好cordova项目之后,在项目里开发调试好在去创建插件目录 如何在cordova项目里创建呢,在android文件夹下面的res/xml/config.xml里去加入插件 例如 ...

  3. Signs of a poorly written jQuery plugin 翻译 (Jquery插件开发注意事项,Jquey官方推荐)

    原文链接:http://remysharp.com/2010/06/03/signs-of-a-poorly-written-jquery-plugin/ 原文作者:remy sharp So far ...

  4. 最近给几个CRM软件配套开发了Outlook插件,讲讲Outlook插件开发注意事项

    原始出处:www.cnblogs.com/Charltsing/p/OutlookAddinsTips.html联系QQ:564955427 从去年到现在,写了四五个Outlook插件,其中两个是给C ...

  5. 快速开发Grunt插件----压缩js模板

    前言 Grunt是一款前端构建工具,帮助我们自动化搭建前端工程.它可以实现自动对js.css.html文件的合并.压缩等一些列操作.Grunt有很多插件,每一款插件实现某个功能,你可以通过npm命名去 ...

  6. 【技术·水】浅谈Dism++清理插件开发

    前言 昨天我发布了NCleaner,一款Dism++清理插件(地址:http://bbs.pcbeta.com/viewthread-1692182-1-1.html) 有些人想要我开源NCleane ...

  7. 读<jQuery 权威指南>[5]-插件

    一.说明 jQuery插件官网:http://plugins.jquery.com/ 使用插件时引用顺序:插件引用要位于主jquery库之后. 二.插件应用实例 演示插件jquery.validate ...

  8. (转)android平台phonegap框架实现原理

    (原文)http://blog.csdn.net/wuruixn/article/details/7405175 android平台phonegap框架实现原理 分类: Android2012-03- ...

  9. [转载]Firefox插件(plugins)开发实用指南

    转自: http://huandu.me/2010/02/11/595/ Firefox插件可实现强大功能,但其中麻烦事情不少.写这个实用指南首先是为了方便自己记忆,免得以后再次栽倒一些坑里面,如果能 ...

随机推荐

  1. 第三节 - centos 内核启动、救援模式、 ls 、目录结构

    Linux 第三节一.CentOS 启动: 1.内核引导: 1.win/linux 通电,2.BISO自检(CPU,内存,硬盘等 | U盘.光驱.网卡.硬盘启动 通过MBR知道内核内存硬件驱动位置并加 ...

  2. 如何写一个SSH项目(三)如何进行交互的

    下面以登录为例子,展示从前台到后端的一整套流程并进行分析. 首先介绍一下我的SSH的分层结构 action和service一起是业务逻辑层          action层调用service层 dao ...

  3. Golang丰富的I/O----用N种Hello World展示

    h1 { margin-top: 0.6cm; margin-bottom: 0.58cm; direction: ltr; color: #000000; line-height: 200%; te ...

  4. Linux下创建root权限的账号osadmin

    创建root权限的账号osadmin 命令为: useradd -u 0 -o -g root -G root -d /home/osadmin osadmin 创建成功后验证效果: id osadm ...

  5. C# System.Windows.Forms.NumericUpDown 控件全选其中文字

    num_length.Focus();                    UpDownBase updbText = (UpDownBase)num_length;                 ...

  6. Sql 两个表left join 查左表最时间最大的一条记录显示

    http://bbs.csdn.net/topics/350135010 参考 select *  from a aa left join b bb on aa.id=bb.cid and bb.ad ...

  7. vlc源码研究

    有位传说中的大神告诉我,我的p2p打洞打不通是因为,sdp描述信息中的地址不对 也就是IN IP4 XXX.XXX.X.XXX这一句 我看到确实是个局域网地址,那么vlc在接收到IN IP4 XXX. ...

  8. vue的挖坑和爬坑之css背景图样式终极解决方法

    原问题 #wrapper{ width:100%; height:100%; position:fixed; background-image:url(./img/open_bg.jpg) } 在.v ...

  9. robotframework的学习笔记(十五)----robotframework标准库Collections

    Collections库是RobotFramework用来处理列表和字典的库,官方文档是这样介绍的:A test library providing keywords for handling lis ...

  10. Robot Framework学习笔记(五)------Collections 库

    Collections 库同样为 Robot Framework 标准类库,它所提供的关键字主要用于列表.索引.字典的处理. 1.添加类 在使用之前需要在测试套件(项目)中添加 2.创建字典 字典也是 ...