grunt-inline:一个资源内嵌插件
一、插件简介
将引用的外部资源,如js
、css
、img
等,内嵌到引用它们的文件里去。
二、使用场景
在项目中,出于某些原因,有的时候我们需要将一些资源,比如js脚本内嵌到页面中去。比如我们的html页面中有这么段小脚本,如果这么直接发布到
线上,就会多了一个请求,这从性能优化的角度来说是不合理的。
<scriptsrc="js/log.js"></script>
那么,我们需要做的事情,就是在项目发布上线前,将这段脚本嵌入到html页面里去。当然可以手工完成,但维护成本极高。这里可以通过grunt插件来帮我们完成这个工作,只需要一个命令。
grunt inline
下面,简单讲解下grunt-inline
的配置和使用。这里假设你对grunt
有一定的了解
三、如何使用
这里我们假设项目的目录结构如下
/index.html
/js/log.js
index.html
里引用了log.js
<scriptsrc="js/log.js"></script>
1、安装插件
npm install grunt-inline --save-dev
2、简单配置
grunt.initConfig({
inline: {
demo: {
src: [ 'index.html' ]
}
}
})
3、修改资源引用
很简单,加上个__inline
标记,告诉插件说这个资源应用是要嵌入到页面去的
<scriptsrc="js/log.js?__inline"></script>
4、执行任务
grunt inline
运行完上面命令,log.js
就会被内嵌到index.html
里,生成结果如下所示
<script>// 这段脚本会被内嵌var Log = {
init: function(opt){
opt = opt || {};
}
};
</script>
四、更多用法
grunt-inline
除了用来内联js文件外,还可以用来内联css、img文件。除此之外,好支持对内联的js、css文件进行压缩。
1、内联css、img文件
内联css文件
这里有个小细节,当css文件被内联进html页面时,css文件里的图片路径也会转换成相对于html页面的相对路径。
<linkrel="stylesheet"href="css/main.css?__inline" />
内联img文件
图片会被转成对应的base64
字符串后,内联到页面
<imgsrc="img/bg.png?__inline" />
2、压缩js、css文件
很简单,加上相应的配置就可以
grunt.initConfig({
inline: {
demo: {
options: {
cssmin: true, // 压缩css文件
uglify: true // 压缩js文件
},
src: [ 'index.html' ]
}
}
});
同样运行grunt inline
任务,这次会看到不一样的输出
<script>var Log={init:function(i){i=i||{}}};
</script>
写在后面
限于篇幅,这里就只简单介绍了下grunt inline
的简单使用以及配置,详细文档请参考 https://www.npmjs.org/package/grunt-inline
如有问题反馈或建议,可点击这里 https://github.com/chyingp/grunt-inline/issues?state=open
随着前端技术的不断发展,现在做的项目里很多页面里都会有大量的ajax请求,随之而来就有了一些问题:
1.没必要的ajax请求怎么处理?
2.ajax链式调用怎么维护?
ajax链式调用最原始的写法:
$.ajax({ ..., success:function(data){ $.ajax(...); } })
这里ajax链式调用我们当然可以使用Jquery的Queue或者When...Then(Done)实现,但是大量的ajax链式调用,这样写也会导致代码过于复杂。
Jquery里用Queue实现的ajax链式调用:
$.queue("myAjaxQueue",[ function(){ $.ajax({ ..., success:function(data){ //do something $.dequeue("myAjaxQueue"); } }) }, function(){ $.ajax({ ..., success:function(data){ //do something $.dequeue("myAjaxQueue"); } }) } ]); $.dequeue("myAjaxQueue")
When...Then(Done)实现的链式调用:
$.when($.ajax({ ... }), $.ajax({ ... })).done(function (xhr1, xhr2) { //do something });
为了解放自己的双手,少写几行代码,于是决定自己写一个Ajax队列管理器,这里第一个遇到的问题是,怎么让后面的ajax请求知道什么时候轮到他们执行,显然我必须在ajax回调里发出通知,这里我用了函数劫持来动态添加发出通知的代码:首先定义一个函数劫持的封装函数:
/// <summary>通用的函数劫持定义</summary> /// <param name="obj" type="Object">被劫持的对象</param> /// <param name="method" type="String">被劫持的方法名</param> /// <param name="hookLogic" type="Function">劫持逻辑</param> /// <param name="beforeMethod" type="Boolean">是否在原函数逻辑执行之前执行</param> hookMethod = function (obj, method, hookLogic, beforeMethod) { var _method = obj[method]; if (!!_method) { obj[method] = function () { if (beforeMethod) { hookLogic.apply(this, arguments); _method.apply(this, arguments); } else { _method.apply(this, arguments); hookLogic.apply(this, arguments); } } } };
然后Ajax队列管理器算是有着落了:
AjaxQueue = function (name) { /// <summary>Ajax队列管理器</summary> /// <param name="name" type="String">队列名称</param> this._name = name; this._requests = [{}]; $(document).queue(this._name, []); } AjaxQueue.prototype = { Request: function (key, xhrOption) { /// <summary>将Ajax请求放入队列</summary> /// <param name="key" type="String">Ajax请求标示,用于管理Ajax状态</param> /// <param name="xhrOption" type="Object Literal">JQuery Ajax对象参数选项</param> var self = this; if (!!xhrOption.complete) { utils.hookMethod(xhrOption, "complete", ajaxHook, false); } else { utils.hookMethod(xhrOption, "success", ajaxHook, false); utils.hookMethod(xhrOption, "error", ajaxHook, false); }; function ajaxHook() { $(document).dequeue(self._name); } $(document).queue(self._name, function () { self.Abort(key);//取消未完成的相同请求 xhr = $.ajax(xhrOption); self._requests.push({ key: key, xhr: xhr }); }); return self; }, Abort: function (key) { var self = this; $.each(self._requests || [], function (i, req) { if (req.key === key) { try { req.xhr.abort(); } catch (err) { } } }); }, Run: function () { $(document).dequeue(this._name); return this; } };
里面集成了ajax链式调用、取消多余Ajax请求之功能,本文有任何不足之处,还望各位大虾指教。