Package.js  现代化的JavaScript项目make工具


Posted in Javascript onMay 23, 2012

Package.js项目地址:http://code.google.com/p/package-js/ 

Package.js是一个很方便的JavaScript包依赖管理及Make工具。它的设计目标是使浏览器端的JavaScript Component/App 开发更加模块化。如果您只是在开发一个小型的网站,只会混杂在HTML中写几行JS代码用于改善一下用户体验,那么Package.js也许并不适合您。如果您正在开发一个中到大型的WebApp,有几十甚至几百几千个JS文件和CSS文件、HTML模板文件,如果您正在为管理这些JS模块之间的依赖和加载而烦恼,为发布到生产环境时将JS文件合并打包而写Makefile写得头晕,那么,Package.js,这就是你想要的!赶快来了解并使用Package.js吧! 

Package.js主要包含两个部分

运行在浏览器中的,用于define及import模块的JS库API
运行在node.js环境,将所有JS包及其依赖的CSS及HTML文件合并的make工具

Package.js浏览器端的API参照了CommonJS/AMD规范,兼容此规范的最简单形式,并在此基础扩展了一些语法,以便于开发包含CSS及HTML模板的JavaScript UI组件。

直接来看一下使用Package.js开发的项目的目录结构吧,简单明了:

Test 
├── dom 
│ └── Style.js #命名空间为Test.dom.Style的模块文件 
├── init.js #根命名空间初始化文件 
├── _nsconf_.js #Package.js会读取的配置文件 
├── ui 
│ ├── Button 
│ │ ├── img 
│ │ │ └── bg.png 
│ │ ├── init.js #Test.ui.Button命名空间的模块文件 
│ │ ├── style.css #UI组件的CSS文件 
│ │ └── tpl.html #UI组件的HTML模板文件 
│ └── Form 
│ ├── init.js 
│ ├── style.css 
│ └── tpl.html 
├── util 
│ └── Cookie.js #命名空间为Test.util.Cookie的JS包 
└── _xproxy_.html -> ../Package/_xproxy_.html #此文件为Soft Link指向Package.js源码中的Package/_xproxy_.html,用于跨域加载HTML模板文件

使用Package.js,模块的定义语法——
Root/ui/Button/init.js代码:
Package.define("Root.ui.Button",["Root.ui.Pane","Root.util.Tpl","Root.util.Event"], 
function (Pane,Tpl,Event) { 
//Pane为Root.ui.Pane 
//Tpl对应Root.util.Tpl 
//依此类推 
//..... 
});

与CommonJS的AMD规范不同,在Package.js的语法中,一个JS模块,不但可以依赖其它JS包,还可以依赖CSS及HTML模板文件、及其它的JSON数据文件,并在运行时,获取到依赖的其它文件的内容。定义语法如下:
Package.define("NS.ui.Button",["MT.ui.Component"], 
{ 
tpl:"tpl.html", 
_style:"style.css" 
},function (Component) { 
//通过this.assets.tpl访问tpl.html内容 
var bgImgUrl=this.path+"img/bg.png",tpl=this.assets.tpl; 
function Button(opt) { 
//也可以通过当前Package对象的_pkgMeta_属性访问assets 
this.tpl=String2Dom(opt.tpl || Button._pkgMeta_.assets.tpl); 
} 
return Button; 
})

在浏览器中,可以使用下面的方法导入一个JS模块,
在导入的过程中,Package.js自动帮您做了后勤工作:1、加载这个模块的依赖模块。2、加载依赖的HTML及CSS文件。
Package.imports(["Root.ui.Button"],function (Button) { 
var btn=new Button(); 
btn.renderTo(document.body); 
});

在开发时,为了模块化,您需要将JS分成一个一个小的模块文件,但发布到生产环境时,为了加载速度上的考虑,您需要将这些JS文件合并成单个的JS文件并压缩,同样,CSS文件也要合并到一起。
//您的打包配置文件 
//build-config.json文件内容 
{ 
"staticUrls": {"defaults":"http://statics.iwt.macrotarget.com/jslibs/"}, 
"nsconfs":["http://www.cnblogs.com/statics/jslibs/XLib/_nsconf_.js"], 
"includes":["XLib.apps.MainApp","XLib.ui.*"], 
"compress":true //使用UglifyJS和UglifyCSS进行压缩 
}

借助Package.js,完成这个功能,您只需要写三四行JSON配置代码,执行一个命令,就一切OK了。
#执行命令 
build.js build-config.json js all.min.js 
build.js build-config.json css all.min.css 
#腰不酸了,腿不疼了!

引用

PS:build.js还帮您做掉一个小事:将CSS文件中的background:url()之类的相对路径转换成绝对URL。您在开发时,CSS中url()始终只需要写相对路径,在部署到生产环境时,build.js合并后的CSS会自动将其转换成绝对URL。甚至,如果你有使用IE6 Png AlphaImageLoader滤镜,使用wui4ie6的loader,您在开发时仍然可以在src=里写相对路径,在开发模式下,Package.js也会自动生成使用绝对URL的CSS Rule,在打包时也会对 AlphaImageLoader的src作转换,CSS中永远不需要写绝对URL

Package.js相比于其它模块加载器及AMD实现(RequireJS,SeaJS...)有什么优势或缺点?

Package.js是面向Web App Framework开发,定义语法及文件目录结构较严格(或者说稍显复杂),只使用AMD规范中最简单的一种define语法
Package.js将JS模块对CSS及HTML文件的依赖与对其它JS模块的依赖在define写法上区分开来,并且在build.js中也包含了对CSS、HTML、JSON打包的处理
(TOT)包含对IE6 CSS的特殊照顾(没办法,我们自己的项目需要)
增加PackageMeta,一个JS模块在运行时可以知道自己的URL
...如果算缺点的话:不与CommonJS AMD规范完全兼容
build时支持三种导出模式:includes,deps,all
开发模式下更方便:使用_xproxy_.html跨域加载,无需代理。使用_nsconf_.js,无需配置paths。

听完这些简单的介绍或许您对Package.js已经跃跃欲试了,在使用之前,您可以参考下 
Package.js的详细文档:http://package-js.googlecode.com/hg/docs/Package.html。 

好!不要再用落后的方式开发JavaScript App,不要再做Out Man,赶快使用Package.js吧 ^O^ 

Javascript 相关文章推荐
javascript与cookie 的问题详解
Nov 11 Javascript
JS获取select-option-text_value的方法
Dec 26 Javascript
一个实用的图片切换支持点击切换和自动轮播
Sep 09 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
May 04 Javascript
jquery简单倒计时实现方法
Dec 18 Javascript
js点击按钮实现水波纹效果代码(CSS3和Canves)
Sep 15 Javascript
Javascript 实现放大镜效果实例详解
Dec 03 Javascript
jQuery中的一些小技巧
Jan 18 Javascript
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
Nov 27 Javascript
vue实现未登录跳转到登录页面的方法
Jul 17 Javascript
浅谈layui 绑定form submit提交表单的注意事项
Oct 25 Javascript
js实现随机圆与矩形功能
Oct 29 Javascript
检测input每次的输入是否合法遇到汉字输入就有问题
May 23 #Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
May 23 #Javascript
setTimeout的延时为0时多个浏览器的区别
May 23 #Javascript
jQuery 瀑布流 绝对定位布局(二)(延迟AJAX加载图片)
May 23 #Javascript
jQuery 瀑布流 浮动布局(一)(延迟AJAX加载图片)
May 23 #Javascript
Javascript 面向对象(三)接口代码
May 23 #Javascript
Javascript 面向对象(二)封装代码
May 23 #Javascript
You might like
无JS,完全php面向过程数据分页实现代码
2012/08/27 PHP
基于php socket(fsockopen)的应用实例分析
2013/06/02 PHP
浅析51个PHP处理字符串的函数
2013/08/02 PHP
简单实用的网站PHP缓存类实例
2014/07/18 PHP
php+mysql实现无限分类实例详解
2015/01/15 PHP
PHP合并discuz用户脚本的方法
2015/08/04 PHP
Smarty模板配置实例简析
2019/07/20 PHP
javascript判断单选框或复选框是否选中方法集锦
2007/04/04 Javascript
那些年,我还在学习jquery 学习笔记
2012/03/05 Javascript
浅析JQuery获取和设置Select选项的常用方法总结
2013/07/04 Javascript
js出生日期 年月日级联菜单示例代码
2014/01/10 Javascript
jquery ajax,ashx,json的用法总结
2014/02/12 Javascript
Javascript 浮点运算精度问题分析与解决
2014/03/26 Javascript
JQuery使用$.ajax和checkbox实现下次不在通知功能
2015/04/16 Javascript
JQuery中Text方法用法实例分析
2015/05/18 Javascript
七个不允许错过的jQuery小技巧
2015/12/21 Javascript
jQuery qrcode生成二维码的方法
2016/04/03 Javascript
Angularjs中使用指令绑定点击事件的方法
2017/03/30 Javascript
node.js连接MongoDB数据库的2种方法教程
2017/05/17 Javascript
浅谈Vue2.0父子组件间事件派发机制
2018/01/08 Javascript
详解如何在项目中使用jest测试react native组件
2018/02/09 Javascript
vue选项卡切换登录方式小案例
2019/09/27 Javascript
Python自定义线程池实现方法分析
2018/02/07 Python
Python cookbook(数据结构与算法)保存最后N个元素的方法
2018/02/13 Python
分享8个非常流行的 Python 可视化工具包
2019/06/05 Python
PyTorch中反卷积的用法详解
2019/12/30 Python
简单了解python shutil模块原理及使用方法
2020/04/28 Python
Python操控mysql批量插入数据的实现方法
2020/10/27 Python
Ray-Ban雷朋西班牙官网:全球领先的太阳眼镜品牌
2018/11/28 全球购物
简述synchronized和java.util.concurrent.locks.Lock的异同
2014/12/08 面试题
系统管理员的职责包括那些?管理的对象是什么?
2013/01/18 面试题
毕业生求职推荐信
2013/11/04 职场文书
医德医魂心得体会
2014/09/11 职场文书
二手房购房协议书范本
2014/10/05 职场文书
领导欢送会主持词
2015/07/06 职场文书
《大禹治水》教学反思
2016/02/22 职场文书