********************************************************************
* 版权声明
*
* 本文以Creative Commons的发布,请严格遵循该授权协议。
* 本文首发于博客园, 此声明为本文章中不可或缺的一部分。
* 作者网名: 浪子
* 作者EMAIL:dayichen (at)163.com
* 作者BLOG: Http://Www.Cnblogs.Com/Walkingboy
*
********************************************************************
[SmartScript]js类库管理不再发愁
-Written by 浪子@cnblogs.com (07-02-07)
摘要:
js文件路径?版本更新,客户端缓存更新?这些问题是否一直困扰你?
为什么我不能像c#一样,using一下所需要的js类库,就可以引用类库的功能,而不必要去管src,管当前的客户端缓存是否最新?
正所谓,只有想不到的没有做不到的,依据最近所得思路制作了SmartScript,轻松搞定这些问题。
一、脚本路径:
当你的项目中js文件越来越多,你的页面层次越来越深,每次都要仔细的处理js对应的url,保证不会引用到错的地址。
当Asp.net 2.0开始使用资源文件代替以往的script文件的时候,我们对js的引用开始越来越方便,大部分的控件厂商已经都使用了内嵌的脚本资源,我们的项目、类库、自定义控件,都无一例外的模仿使用了这个方法。
毫无疑问,这是个绝妙的方法,我们不必要再担心,我们的控件不知道会用在那个结构底下,它跟js的相对路径是什么,页面里再也看不到"http://www.cnblogs.com/"如此复杂的地址了。
但是内嵌的脚本也给了我们麻烦,每次修改js都需要rebuild整个项目!
二、版本更新:
rebuild的项目我忍了,但是不能容忍的是js文件的版本更新了,但是客户端的缓存却一直没有更新,这下子晕了,然后我要去客户端一个个清除缓存嘛?显然这是不可能了。
或者我修改所有的js链接地址?Oh,My god。开发人员准会每天骂你一百遍,想象下当你的js更新频繁的时候......
三、我的解决方案SmartScript:
首先,对于脚本的路径,我们肯定还是要保留HttpHandler的处理方式,因为它确实非常的便利。但是我们可以不使用内嵌资源,我直接读文件流,不是一样嘛:)
对于版本更新,只要为每次的js连接增加版本信息就好了,这样子版本一变,文件名也就改变,自然没有存在更新缓存的意义了,因为它对IE来说本身就是一个新的js。
要处理这些问题,首要规避的问题就是hardcode的js引入
1. <script type="text/javascript" src="boot.js"></script>
取而代之是,我希望可以像c#一样,使用一个特定的指令来引入,比如
1. $using("boot");
思路慢慢的清晰了,看下我的完整的boot.js启动代码![]()
var __SS =
{} ;
__SS.Loads = new Array();
function $using()
{
for(var i=0;i<arguments.length;i++)
{
__SS.Loads.push(arguments[i]);
}
} ;
function $load()
{
if(__SS.Loads.length>0)
{
document.write('<script type="text/javascript" src="SmartScripts.axd?res='+__SS.Loads.join("$")+'&ver='+__SS.Version+'"><' + '/script>');
}
} ;
![]()
OK。看到了,我们是用SmartScripts.axd来绑定js的HttpHandler
<httpHandlers> <add path="SmartScripts.axd" type="SmartScript.ScriptHandler,SmartScript" verb="*" validate="false"/> </httpHandlers>
然后使用$Load统一载入js,为什么要多这一步呢?主要是为了以后扩展的方便,特别是多线程下载(请参考Jeffrey Zhao的性能优化(7)相关文章),还有一点就是把零零碎碎的小文件合并成一个大文件下载。
可能有人已经发现上面的一个bug,__SS.Version,没有定义?:),缓存的问题就是在这里解决的,首先这个版本信息是被我配置在config文件里面的,每次都会动态读取,这样子如果更新js文件,只要同时更新config的版本信息,这段js自动就会使用新的版本进行替换。看下配置文件的样子吧
<?xml version="1.0" encoding="utf-8" ?> <SmartScript cache="true" compress="false" gzip="true" ver="0.11.2" > <Scripts> <Script name="boot" url="boot.js"/> <Script name="KINN" url="KINN/KINN.js"/> <Script name="KINN.UI" url="KINN/UI.js"/> </Scripts> </SmartScript>
是否缓存js(对boot程序作了特别处理,不作缓存,这样子保证版本更新的时候,boot一直都是最新的),是否压缩js(语法),是否采用gzip,还有版本信息。
然后才会js作了个别名处理。
四、扩展&Demo
东西虽小,但是却是个无侵入,开放的第三方脚本管理方案,它让我可以任意的引用第三类库,也可以灵活的替换。而本身又是无框架依赖的:)
其实我原来的设想还有一个更重要的一步,就是自动依赖:在配置文件里面设置好每次js的互相依赖情况,然后自动监测,自动会按所需顺序逐个帮你加载所需的js文件,不过一直没有想到好的实现方法,所以暂时放弃了,留待后面有机会的时候再扩展吧。
SmartScripts的使用,因为太简单了,简单得我都不知道怎么写,帖小段代码吧:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> <script type="text/javascript" src="SmartScripts.axd?res=boot"></script> <script type="text/javascript"> $using("KINN"); $using("KINN.UI"); $load(); </script> </head> <body> <form id="form1" runat="server"> <div> <input type="button" onclick="KINN();" value="KINN" /> <input type="button" onclick="UI();" value="KINN.UI" /> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /></div> </form> </body> </html>
页面里面引入2个文件,别名分别为KINN和KINN.UI.
两个button分别调用了KINN和KINN.UI里面的方法
demo代码下载:http://www.cnblogs.com/Files/walkingboy/SmartScript.WebTest.rar