grunt 插件开发注意事项
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 插件开发注意事项的更多相关文章
- Grunt 插件开发与调式
1 grunt是什么 官方网站解释的很清楚,http://gruntjs.com/ http://gruntjs.cn/ 它是一种javascript任务运行器,对于需要反复重复的任务,例如压缩.编译 ...
- cordova插件开发注意事项
1. 编写插件,先创建好cordova项目之后,在项目里开发调试好在去创建插件目录 如何在cordova项目里创建呢,在android文件夹下面的res/xml/config.xml里去加入插件 例如 ...
- 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 ...
- 最近给几个CRM软件配套开发了Outlook插件,讲讲Outlook插件开发注意事项
原始出处:www.cnblogs.com/Charltsing/p/OutlookAddinsTips.html联系QQ:564955427 从去年到现在,写了四五个Outlook插件,其中两个是给C ...
- 快速开发Grunt插件----压缩js模板
前言 Grunt是一款前端构建工具,帮助我们自动化搭建前端工程.它可以实现自动对js.css.html文件的合并.压缩等一些列操作.Grunt有很多插件,每一款插件实现某个功能,你可以通过npm命名去 ...
- 【技术·水】浅谈Dism++清理插件开发
前言 昨天我发布了NCleaner,一款Dism++清理插件(地址:http://bbs.pcbeta.com/viewthread-1692182-1-1.html) 有些人想要我开源NCleane ...
- 读<jQuery 权威指南>[5]-插件
一.说明 jQuery插件官网:http://plugins.jquery.com/ 使用插件时引用顺序:插件引用要位于主jquery库之后. 二.插件应用实例 演示插件jquery.validate ...
- (转)android平台phonegap框架实现原理
(原文)http://blog.csdn.net/wuruixn/article/details/7405175 android平台phonegap框架实现原理 分类: Android2012-03- ...
- [转载]Firefox插件(plugins)开发实用指南
转自: http://huandu.me/2010/02/11/595/ Firefox插件可实现强大功能,但其中麻烦事情不少.写这个实用指南首先是为了方便自己记忆,免得以后再次栽倒一些坑里面,如果能 ...
随机推荐
- 10 Easy Steps to a Complete Understanding of SQL
原文出处:http://tech.pro/tutorial/1555/10-easy-steps-to-a-complete-understanding-of-sql(已经失效,现在收集如下) Too ...
- 使用 PyCharm 添加 第三方 依赖库
背景 最近开始搞python, 需要帮助算法同事一起调试程序,在本地安装python以后使用 pip 来安装第三方库. 但是算法同事一直使用的是PyCharm 这个IDE,所以需要与他一起调试的时候也 ...
- Errors are values
原文地址 https://blog.golang.org/errors-are-values Go程序员之间(特别是这些刚接触Go语言的新人)一个常见的讨论点是如何处理错误.谈话经常变成为对如下代码序 ...
- ASP.NET如何通过后台数据库提供的链接播放视频(不使用外置插件)
1.后台视频数据库: 2.aspx中的关键代码: <asp:DataList ID="DataList2" runat="server" DataKeyF ...
- 砸黑板! 正则表达式!!!re 模块
模块是什么? 一个模块就是一个包含了 python 定义和声明的文件,文件名就是模块名字加上.py 的后缀. 但其实 import 加载的模块分为四个通用类别: 1:使用 python 编写的代码(. ...
- Standard PHP Library(SPL)中的数据结构
SPL提供了一组标准数据结构. SplDoublyLinkedList Class:双向链表(DLL)是在两个方向上相互链接的节点列表.当底层结构是dll时,迭代器的操作.对两端的访问.节点的添加或删 ...
- Web App、Hybrid App与Native App
在这个App的时代,转战了前端,一直接触的都是pc, 离out不远了. 那么接下来,app是我接下来半年的重点,为什么是半年,因为时间不多了. 因为是前端,那么我的重心肯定是 Web App, Hyb ...
- [Spark性能调优] 第二章:彻底解密Spark的HashShuffle
本課主題 Shuffle 是分布式系统的天敌 Spark HashShuffle介绍 Spark Consolidated HashShuffle介绍 Shuffle 是如何成为 Spark 性能杀手 ...
- 自学Aruba1.2-WLAN一些基本常识
点击返回:自学Aruba之路 自学Aruba1.2-WLAN一些基本常识 1. LAN.WAN.WLAN.WIFI术语 1.1 局域网(Local Area Network,LAN) 是指在某一区域内 ...
- Java学习笔记13(面向对象六:super)
在创建子类对象时,父类的构造方法会先执行,因为子类中所有构造方法的第一行有默认的隐式super();语句 注意:父类构造方法第一行也有隐式的super(); 所有类都有一个"祖宗类" ...