`

简单聊一聊百度的开源JS库:Tangram

阅读更多
简单聊一聊百度的开源JS库:Tangram


最近百度开源了他们的"js框架"Tangram , 之前听说这件事时,还是很期待的, 但是当真正看到Tangram时 还是有些失望.

打算在这里简单谈一谈我对它一些看法.
这里所说的"看法"几乎没有技术相关的东西,详细的技术分析 稍后再写, 毕竟还没有把代码通读一遍,不好妄下结论.


首先声明一点, 虽然百度公司的名声似乎不好, 但是百度的技术人员是值得敬佩的,他们几乎个顶个的都是牛人.
这个绝对不是拍马屁(没必要拍), 我参加过很多技术交流会,每次凡是由百度技术人员进行的演讲,都会让我赞叹不已.
而百度在技术社区积极分享的一些技术资料也很有含金量.

下面进入正题吧, 说一说Tangram.


=====================
原来是个"库"

这个绝对是我个人的问题.
我一直期待着一个'开源的js框架",可是 最后拿到手里的却根本不是一个框架. 基本上只是"把一个一个(或者说一组一组)的功能函数,累积到一起, 最后产生的一个工具包".

到底是框架 还是 工具包 其实无所谓, 各有各的长处, 并不是说工具包就不如框架.
不过还是有点小小的失望.

=====================
让人不爽的"baidu."前缀.

这点也是网上反感最大的. 也许名字本来是无关紧要的东西. 但是事实并非如此.
@lifesing 在<关于jQuery和YUI, 还有KISSY>这篇文章中 ,
有对"软件名称"的一点点讨论.其中部分观点还是很有价值的,节选如下:
"
YUI 的开发团队,太强烈的 YAHOO 色彩,真有可能是成也萧何,败也萧何。
如果真的哪一天 YAHOO 彻底没落,YUI 可能真的会很快成为历史。

有公司在背后支持是没问题的,但不能太放到明面上说,更不能产生强依赖。
比如提起 jQuery,我们并不会立刻想到 Mozilla. Mozilla 只是默默的支持者。
Prototype 和 MooTools 等也是,我们不 google 一下,甚至不知道 Prototype 和 MooTools 背后的公司是哪些。

YUI 的 Y, 使得 YUI 很难彻底开放开源。
"
这个问题百度Tangram自己也已经意识到了, 承诺未来会改变, 期待.

=====================
代码组织 & 需求
因为要满足"函数级别的按需构建", 所以tangram选择了一种通常很少见的代码组织方式:
每一个公共函数 一个单独的文件.
同时 在定义每一个函数的时候 都使用 全名(含有百度前缀和模块名称等),例如:
下面6个函数, 分别放在
tangram\baidu\dom目录下的 6个js文件中.

// getPosition.js 
baidu.dom.getPosition = function(){}

// getPosition.js 
baidu.dom.setPosition = function(){}

// getPosition.js 
baidu.dom.getStyle = function(){}

// getPosition.js 
baidu.dom.setStyle = function(){}

// getPosition.js 
baidu.dom.removeStyle = function(){}

// getPosition.js 
baidu.dom.removeClass = function(){}


如果我们某个页面只需要其中的前4个, 那么选中后, tangram的构建工具 codesearch 会打包出一个文件,文件内容如下:

baidu.dom.getPosition = function(){}
baidu.dom.setPosition = function(){}
baidu.dom.getStyle = function(){}
baidu.dom.setStyle = function(){}


这个地方, codesearch的设计者明显是偷懒了, 以他们的技术实力, 构建出下面这种 更精简的代码 是完全没有问题:


baidu.extend( baidu.dom , {
	getPosition : function(){},
	setPosition : function(){},
	getStyle : function(){},
	setStyle : function(){}
})



如果不喜欢上面这种方式 构建成这种也完全没有问题:
(function(){ 
	var M=baidu.dom;
	M.getPosition = function(){}
	M.setPosition = function(){}
	M.getStyle = function(){}
	M.setStyle = function(){}
})()



反过来看, 如果源码存放时, 就是按模块一体存放的,如下 放在 baidu/dom.js里
extend( baidu.dom , {
	getPosition : function(){},
	setPosition : function(){},
	getStyle : function(){},
	setStyle : function(){},
	removeStyle : function(){},
	removeClass : function(){}

})

那么根据需求 构建出
extend( baidu.dom , {
	getPosition : function(){},
	setPosition : function(){},
	getStyle : function(){},
	setStyle : function(){}
})

也不是难事.

反正我觉得可以优化的地方很多, 而且使用到的函数越多优势越明显.


而目前百度的 codesearch 工具在构建文件时, 很可能是做完依赖的判断后, 只是简单的读取文件 拼接文件, 而没有做进一步的优化.

所以 我不得不认为"codesearch工具的设计和开发人员偷懒了".

"函数级别的按需构建" 的一个目的是为了让引入的js代码尽可能的小, 但是Tangram现在的做法并没有做到最好.反而在很多地方让代码变得冗长了.

即使上面的做法都不可取, 那么"每一个公共函数 一个单独的文件,函数用全名称定义" 也绝对不是解决"函数级别的按需构建"的最好方案, 更不是唯一方案.

关于代码构建和组织, 我稍后会写一篇我的观点和看法.

我一直很推崇 对IDE友好的 js代码组织方式. 所谓对IDE友好, 就是可以让那些比较流行的IDE可以清楚的显示出 js代码的 outline 以及进行 方法的跳转 查找等. 把函数一个个的拆开存放, 我觉得不是一个好办法.

========================
codesearch 也应该提供下载, 让用户可以在本地构建Tangram

这个没什么好说的, 我觉得这个需求一点也不过分.

========================
开源的目的和意义
看到 Tangram的成员在博客上说 :
"tangram首先还是针对百度产品线的,主要用户也是百度产品线,不是说开源了希望有多少人用这个库,开源更多的是种开放和互相学习的姿态。
"

如果开源的目的不是为了"让更多的人使用这个产品, 让更多的人对产品提出有益的建议, 给更多的用户带去价值, 从用户那里获得不断进步的动力和成就感",
而仅仅是为了"表达百度的一个开放和互相学习的姿态",
那么这种开源是不是可以理解为"面子工程"或"市场行为"?
而对于Tangram的人员来说, 是不是可以理解为只是一个"政绩工程", 只是你们年底KPI考核时的一个正值?

难道开源的意义就是"摆一个姿态给大家看"?

开源者 除了要有一个开放的心态, 也要有梦想有野心, 不管是否有人相信,不管是否能够实现, 至少喊出来, 感动一下自己 也是好的啊.


所以, 我觉得不管 百度 官方是怎么指定的目标, Tangram团队还是应该给自己提供一个更高的目标和要求.

======================

先说这些吧, 具体的技术细节的讨论下次再说.



5
4
分享到:
评论
7 楼 cuixiping 2011-01-04  
lifesinger 写道
有个误区:
考虑 gzip, 方法A的文件体积大小,反而比方式B小,因为重复字串多。
代码组织的粒度,我觉得关键是要有一致性。其它的,都是浮云啊浮云

应该是在build的时候让用户自定义选择输出风格
并注明风格A经gzip后更小,风格B在不gzip的时候较小
6 楼 scottcgi 2010-12-25  
这个框架没有让人使用的冲动
5 楼 berg 2010-12-24  
1. "js框架“,着是我的失误,那天顺手敲上字,没有仔细检查就发布了。我一直认为tangram是一个库,尽管在内部很多人错误的把这个东西叫做“框架”。

2. 命名空间,这个已经有计划修改,就不啰嗦了。

3. codesearch,这个东西的确有很大增强的余地,我赞同第二种大闭包的做法,事实上我们在下个版本就会推出这种打包方式,当然,codesearch也会尽快做出一个本地版。顺便说一下其他几种做法的缺点:1)增加代码体积,lifesinger已经说过了,我认为在这样的case中,体积是一定变大的,就算只有1-2个字节。2)性能会有略微的损失。

4. 函数拆分到文件,在twitter上简单说了一下我的看法,周末我会写文章介绍下,tangram不是特立独行,也不是返古,只是面向的问题域不同罢了。

5. tangram开源,不是姿态,我也不真的期望一下子能给互联网带来什么好处,在我的blog中说的很清楚,一是引入业界开发流程,打破公司开发的一些枷锁,接受来自外部的检验(比如作者你),提高tangram的水平,二是促进国内的交流,至少敝公司后面的开源流程将很顺利,开源项目也会越来越多。
4 楼 fins 2010-12-24  
回 3 楼 :

首先我承认, Tangram现在的架构并不会对软件本身的功能和使用产生什么障碍.

我所讨论的问题 很多时候属于"技术和功能性需求"之外的东西.
很多人可能认为这个东西没有用, 但很多时候 代码的风格和气质, 就好像一个公司的企业文化一样, 它对公司的影响是潜移默化的.

===============================
先来说说你的几个观点.

1.代码合并需要分析语法,对代码重新提取关键字重新组合,不仅复杂,而且容易出错
框架的代码合并工具 必须要加强, 不能因为"工具开发难度大 复杂 容易出错" 就牺牲框架本身的质量.
还是那句话, 代码build工具的开发人员, 不要给自己的懒惰和不担当找任何借口.


2.在不需要baidu.extend的代码里这样做还要另外引入这个extend方法,浪费
extend函数能有多大的成本啊.如果觉得成本大,写成
fins.test = {
...
}
好了.

3.lifesinger说了,体积反而变大了
这个不是一定的.
而且"代码总大小 代码中重复字符数,gzip压缩后大小"三者之间的关系是非线性的.
不能一概而论.



=================================

单独的比较两者优缺点没什么意义 , 因为各有优缺点, 而且对于不同的人 优缺点也有所不同.
百度有强大的测试 QA做保障,还有很多牛人给你们开发辅助工具(如codesearch) 而且模块 框架的大的改动也不太容易发生, 所以很多问题 对于你们来说根本不是问题.

但是放到开源社区来看, 很多你们眼里不是问题的问题 都会成为问题.


方式A
fins.test.getPosition = function(){}
fins.test.setPosition = function(){}
fins.test.getStyle = function(){}
fins.test.setStyle = function(){}

很明显的违背了 DRY原则.



同时 方式A 在语义上面, 也弱化了模块的界限.
使得 fins.test.getPosition 本质上就是一个长名字.
和 fins_test_getPosition / fins$test$getPosition没什么区别.
让整个库显得杂乱无章.

而下面的代码

// fins.test 是一个模块
fins.test = {
  // 这里是原生的基本内容...
}

// 扩展一个模块
extend(fins.test , {
// 这里是扩展的内容
}

显然语义性更强.

当然 你说的那些方式B的缺点我也承认.但是如果方式A 真的如你所说的有很多优点, 而方式B缺点明显. 为什么大多数开源js框架都会选择类似方式B的做法呢?


开源就不能总是按照作者自己的主观看法,多听听大家的声音, 多看看大多数人怎么做的.
并不是所有的"特立独行"都好过"随波逐流"的.


你们内部是不是都认为 一个函数 一个文件的组织方法很好?

3 楼 bang590 2010-12-24  
其实我不明白,从
baidu.dom.getPosition = function(){} 
baidu.dom.setPosition = function(){} 
baidu.dom.getStyle = function(){} 
baidu.dom.setStyle = function(){} 
变成
baidu.extend( baidu.dom , { 
    getPosition : function(){}, 
    setPosition : function(){}, 
    getStyle : function(){}, 
    setStyle : function(){} 
}) 
好处是什么?坏处我倒是可以说一些:
1.代码合并需要分析语法,对代码重新提取关键字重新组合,不仅复杂,而且容易出错
2.在不需要baidu.extend的代码里这样做还要另外引入这个extend方法,浪费
3.lifesinger说了,体积反而变大了

如果仅仅是因为“好看一点”的话,实在没必要这么折腾。而且我也没觉得好看多少

--------------
codesearch 也应该提供下载, 让用户可以在本地构建Tangram

必须的,与tangram相关的东西相信都会开源的

---------------
开源的目的和意义

可能是我写的引起误会了,相信没有一个开源的产品不希望大家都用这个产品,谁不想做jquery那样成功的开源项目?谁不想很多人在github上fork和贡献代码?我的意思是目前tangram主要给百度产品线用,对其他团队现在还没有完善到可以很流畅地像用YUI那样用tangram进行开发。梦想和野心当然是有的,但在实现之前吹嘘这些显得比较什么,反正我是不喜欢这么做。我在前文也提到了这第一次开源的意义,在现阶段我觉得这个意义更大一些。扯到政绩工程和KPI很不靠谱。

2 楼 fins 2010-12-24  
如果考虑gzip的话 很多事情都要换角度思考了 呵呵
很多时候 费了九牛二虎之力 把源码精简了 200K.

结果换算成 gzip, 就少了一两k , 悲剧... :'(

其实大小不是我在意的

我喜欢 看起来清爽.
1 楼 lifesinger 2010-12-24  
有个误区:

// 方式A
baidu.dom.getPosition = function(){} 
baidu.dom.setPosition = function(){} 
baidu.dom.getStyle = function(){} 
baidu.dom.setStyle = function(){} 

// 方式B
baidu.extend( baidu.dom , { 
    getPosition : function(){}, 
    setPosition : function(){}, 
    getStyle : function(){}, 
    setStyle : function(){} 
}) 

考虑 gzip, 方法A的文件体积大小,反而比方式B小,因为重复字串多。

代码组织的粒度,我觉得关键是要有一致性。其它的,都是浮云啊浮云

相关推荐

Global site tag (gtag.js) - Google Analytics