<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.edgarhoo.net/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Edgar's Blog</title>
	
	<link>http://blog.edgar.im</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Mon, 03 Oct 2011 01:43:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.edgarhoo.net/edgar-blog" /><feedburner:info uri="edgar-blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>HexJS诞生记</title>
		<link>http://feeds.edgarhoo.net/~r/edgar-blog/~3/pDCI5lGYJJ8/hexjs-birth-stroy.html</link>
		<comments>http://blog.edgar.im/article/hexjs-birth-stroy.html#comments</comments>
		<pubDate>Mon, 03 Oct 2011 01:43:11 +0000</pubDate>
		<dc:creator>edgar</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[HexJS]]></category>

		<guid isPermaLink="false">http://blog.edgar.im/?p=4</guid>
		<description><![CDATA[这篇是上周在方凳会上分享的同名slide的讲稿。本来应该先写这篇，再从中择几句拼成slide的。不料，现在反了一下。我始终觉得slide若作为资料存档总是不够份量的，不及文章能够沉淀 我对HexJS的定位是一个页面级的module管理器，更重要的是在此基础之上所形成的一套js书写风格。那么，在只有一套书写风格的情况下，对同一功能的实现的思路、方法也许能够趋于相似，这对于团队开发、维护来说，至关重要。我对这一点深有感触，拿运营线的页面来说，无论哪位同学先开发，尔后哪位同学再接手，都不会觉得代码陌生，如同这是自己的代码一般，甚至一张页面多人同时开发再拼起来而它的代码风格也是一致的，因为大家都是基于Pitaya系列约定来开发的。如此，一个团队就一套风格，不再是一人一风格 接下来讲HexJS产生前后的一些思路，或者说是产生HexJS的缘由以及原因 先来看一段代码： //代码1 var readyFunc = [ function fn1(){}, //功能1 function fn2(){}, //功能2 function fn3(){} //功能3 ]; $E.onDOMReady(function(){ for ( var i = 0, len = readyFunc.length; i &#60; len; i++ ){ try { readyFunc[i](); } catch(e) { &#8230; <a href="http://blog.edgar.im/article/hexjs-birth-stroy.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>这篇是上周在方凳会上分享的同名<a href="http://slides.edgar.im/2011/hexjs-birth-stroy.html">slide</a>的讲稿。本来应该先写这篇，再从中择几句拼成slide的。不料，现在反了一下。我始终觉得slide若作为资料存档总是不够份量的，不及文章能够沉淀</p>
<p>我对HexJS的定位是一个页面级的module管理器，更重要的是在此基础之上所形成的一套js书写风格。那么，在只有一套书写风格的情况下，对同一功能的实现的思路、方法也许能够趋于相似，这对于团队开发、维护来说，至关重要。我对这一点深有感触，拿运营线的页面来说，无论哪位同学先开发，尔后哪位同学再接手，都不会觉得代码陌生，如同这是自己的代码一般，甚至一张页面多人同时开发再拼起来而它的代码风格也是一致的，因为大家都是基于Pitaya系列约定来开发的。如此，一个团队就一套风格，不再是一人一风格</p>
<p>接下来讲HexJS产生前后的一些思路，或者说是产生HexJS的缘由以及原因</p>
<p>先来看一段代码：</p>
<pre class="sh_js">
//代码1
var readyFunc = [
    function fn1(){}, //功能1
    function fn2(){}, //功能2
    function fn3(){} //功能3
];

$E.onDOMReady(function(){
    for ( var i = 0, len = readyFunc.length; i &lt; len; i++ ){
        try {
            readyFunc[i]();
        } catch(e) {
            if ( Ali.isDebug ){
                console.info( 'Error at No.' + i + '; ' + e.name + ':' + e.message );
            }
        } finally {
            continue;
        }
    }
});</pre>
<p>不少同学对代码1肯定不陌生，曾经应该风行过，现在去style里搜还能搜出一大堆来。代码1的优点在于，通过try catch来保证各个功能互不干扰，哪怕某个功能失效了出bug了，也不影响其他功能的生效。这从体验上将失效的范围降到最低。有一点需要注意的是，这些功能只能是相互独立的，比较适合于一些小功能。这个风格我没使用过，因为我不喜欢每个文件底部都copy那段onDOMReady的代码</p>
<p>再看下一段代码：</p>
<pre class="sh_js">
//代码2
(function( NS ){
    NS.xxx = {
        init: function(){
            this.fn1(); //功能1
            this.fn2(); //功能2
            this.fn3(); //功能3
        },
        fn1: function(){
            this._fn4();
        },
        fn2: function(){},
        fn3: function(){},
        _fn4: function(){}
    };

    $E.onDOMReady(function(){
        NS.xxx.init();
    }

})( NameSpace );</pre>
<p>代码2的风格我经常用的，通过命名空间将所有页面都纳入到一个体系里，文件间也是经过命名空间的传递达到通信</p>
<p>后来新版旺铺，由琪君创造了下面这段风格：</p>
<pre class="sh_js">
//代码3
(function( $, NS ){
    var ModName = { //功能1
        init: function(){
            this._fn1();
            this._fn2();
        },
        _fn1: function(){},
        _fn2: function(){}
    };

    NS.PageContext.register( 'mod-name', ModName );

})( jQuery, NameSpace );</pre>
<p>当然新版旺铺的底层js还有很多功能，这里只是取一个风格。不容否认，琪君的旺铺js对我是有很大影响的，尽管我并没有真正使用过，主要还是看源码。这段js的其中一个优点在于应用层不再显式的出现DOMReady，将功能的执行统一的管理起来</p>
<p>至此，对我来说，已有的一定的风格累积</p>
<p>接下来讲转折点。其中一个是圈圈项目。从前端质量角度看，这并不是一个成功的项目，甚至因为使用了一个第三方组件，留着一个小问题就上线了。但于我而言，它的复杂程度刚好够我去思考js的写法</p>
<p>看一个现状，圈圈项目中的画报编辑页js：</p>
<pre class="sh_js">
merge.js        //页面级出口文件
    base.js     //画报实例，全局标记变量
    util.js     //公共方法
    upload.js   //图片上传相关功能
    popup.js    //浮出层相关功能
    submit.js   //表单提交相关功能
    done.js     //页面初始化、功能执行</pre>
<p>除了base.js和done.js，其他文件的行数在300至600之间，6个文件间通过FE.info.admin.editpictorial这个命名空间传递数据，采用类似代码2的风格，只不过分散在各个文件。DOMReady只在done.js中存在，其他文件的初始化、执行都依次在done.js运行</p>
<p>对此不满意的点有：</p>
<ol>
<li>文件拆分不完全
<p>看上去文件根据功能拆分，还不错。但实际上，upload.js仍然会对util扩展方法，某些公共属性不得不在其他文件定义</p>
</li>
<li>功能依赖不清晰
<p>若其他同学要去改个东西，很难在短时间内理清楚。尽管已尽量让upload.js、popup.js、submit.js三者之间没有通信，但util的方法过多，而没有很好的分类</p>
</li>
<li>某功能相关的方法跟功能主体间隔太远，不好理解
<p>某些功能的主体和其输出接口分散在文件各处甚至两个文件，这么做的原因是要达到只允许util等公共变量才能传递数据</p>
</li>
<li>曲折做到只在DOMReady之后取节点
<p>不少节点在多文件使用，且无法在util初始化的去取，只能在done.js中取好再以入参的方式传给各文件的初始化函数。</p>
</li>
<li>难以做到一个节点只取一次
<p>大部分节点可以做到只取一次，仍有不少不得不多取几次</p>
</li>
</ol>
<p><strong>这个现状让我很不满意！</strong></p>
<p>项目时间基本上都是很紧的，根本没时间可以去重构或梳理，希望能在一开始就能够不产生这些问题</p>
<p>希望解决的问题：</p>
<ul>
<li>文件拆分可以完全</li>
<li>文件间的信息通信、共享方便</li>
<li>功能相互依赖清晰</li>
<li>节点在DOMReady之后取</li>
<li>一个节点尽可能只取一次</li>
</ul>
<p>另一个转折点是alibar。差不多也在圈圈项目同时间，alibar的改动非常频繁，作为全站统一区块，稳定性是最重要的。在频繁改动的驱动下，原有的代码风格完全不能适应，期望功能彼此独立，连视觉上也期望彼此离得远些，于是改成如下风格：</p>
<pre class="sh_js">
var checkSignIn = { //功能1
    init: function(){ this._fn(); },
    _fn: function(){ register( [ _addTip ] ); }
};

var changeDone = { //功能2
    init: function(){ this._fn(); },
    _fn: function(){}
};

var _addTip = { //功能3
    init: function(){}
};

register( [ checkSignIn, changeDone ] );</pre>
<p>这样，多个功能的切换、更新换代，相对来说简单得多了，也放心得多</p>
<p>到这个时候，已经在想需要一套新的书写风格，但具体怎样还很模糊</p>
<p>若没有七月的首页改版，也许HexJS会来得晚些。不过，首页改版从四月开始闹起，势必是要改版的</p>
<p>对于这回首页改版，无论之前数回的胎死腹中，还是真正落地，我们都给予了很大的期待，我们想尝试的东西实在太多</p>
<p>那么对于js的这套书写风格也提上真正的日程</p>
<p>CommonJS的火爆应该没有一个前端不去关注下的，对于它所制定的一系列API规格，我是觉得也许真的会成为一个js的生态，实在没什么理由拒绝的</p>
<p>于是，便去找它的实现，看看哪个能直接拿来用的。其实根本不用找，SeaJS、OzJS、RequireJS这三个同样如雷贯耳的</p>
<p>OzJS文档缺失，首先排除掉，RequireJS实在有些庞大，只剩下SeaJS</p>
<p>从我的观点来看，SeaJS已经足够强大，这篇blog的产生也即意味着我并没有选择SeaJS，主要原因为以下三点：</p>
<ol>
<li>文件拆分过细
<p>若一个module一个文件，当页面复杂时，碎文件过多。另一方面，从实际操作来讲，也难以做到一个文件只一个module，除非一个module包含数个功能，而这为我所不愿</p>
</li>
<li>部署问题
<p>上线的文件必然需要合并。虽SeaJS自有打包工具，效果似乎并不完美，况且我们已有较成熟的merge机制。对于动态加载，我认为只有组件级文件才有必要，页面级的文件实在没这个必要，而fdev-v4对组件的动态加载也同样处理得比较好了</p>
</li>
<li>维护问题
<p>在SeaJS未全站推广的情况下，其他同学来维护有使用SeaJS的页面时将比较麻烦。现在绝大部分同学仍然在windows系统下开发</p>
</li>
</ol>
<p>从我的观察，觉得SeaJS不过是另一套Kissy，并不会甘心止于module loader</p>
<p><strong>其实我想要的是一种书写风格，而不是框架/库</strong></p>
<p>SeaJS更适合于初创网站，对中文站这庞大而古老且自有体系的站来说，它并不适合。提句题外话，既然fdev-v4没有选择SeaJS而选择了jQuery作为核心，那么现在fdev-v4已渐近成熟的情况下，也难以再回去使用它了</p>
<p>下面简单介绍下HexJS，它的特点有：</p>
<ol>
<li>专注于module机制，不涉及script加载</li>
<li>module定义与执行的分离</li>
<li>各module的执行相互独立</li>
<li>保留原有书写习惯</li>
<li>API简洁</li>
<li>目前gzip之后只有766字节</li>
</ol>
<p>HexJS只符合一部分CommonJS的Modules/1.1.1规范，具体API可以参考其<a href="http://hexjs.edgarhoo.org/manual.zh-cn.html">使用手册</a></p>
<p>最后分享下HexJS的命名由来：</p>
<pre class="sh_js">
module -> 块 -> 积木 -> 蜂窝 -> 六边形 -> Hexagon -> HexJS</pre>

			  <p><b><a target="_blank" href="http://blog.edgar.im/?cof_write=4">Write a quick comment</a></b></p><hr />
<p><small>© Edgar Hoo for <a href="http://blog.edgar.im">Edgar&#039;s Blog</a>, 2011. |
<a href="http://blog.edgar.im/article/hexjs-birth-stroy.html">Permalink</a> |
<a href="http://blog.edgar.im/article/hexjs-birth-stroy.html#comments">No comment</a> |
Post tags: <a href="http://blog.edgar.im/tag/hexjs" rel="tag">HexJS</a><br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
<img src="http://feeds.feedburner.com/~r/edgar-blog/~4/pDCI5lGYJJ8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.edgar.im/article/hexjs-birth-stroy.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.edgar.im/article/hexjs-birth-stroy.html</feedburner:origLink></item>
		<item>
		<title>Hello world!</title>
		<link>http://feeds.edgarhoo.net/~r/edgar-blog/~3/TuN7l7WgbqE/hello-world.html</link>
		<comments>http://blog.edgar.im/article/hello-world.html#comments</comments>
		<pubDate>Mon, 03 Oct 2011 00:57:14 +0000</pubDate>
		<dc:creator>edgar</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.edgar.im/?p=1</guid>
		<description><![CDATA[Welcome to WordPress. This is your first post. Edit or delete it, then start blogging! 1 comment(s) for this post: Mr WordPress: 03 Oct 2011 Hi, this is a comment.To delete a comment, just log in and view the post&#039;s &#8230; <a href="http://blog.edgar.im/article/hello-world.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!</p>

				<div>
					<h4>1 comment(s) for this post:</h4><ol>
						  <li><img alt='' src='http://0.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=32' class='avatar avatar-32 photo avatar-default' height='32' width='32' /><i>Mr WordPress:</i>
							<br />
							<small><a rel="nofollow" href="http://blog.edgar.im/article/hello-world.html#comment-1">03 Oct 2011</a></small>
							Hi, this is a comment.<br />To delete a comment, just log in and view the post&#039;s comments. There you will have the option to edit or delete them.
						  </li>
					  </ol>
				  </div>
			  <p><b><a target="_blank" href="http://blog.edgar.im/?cof_write=1">Write a quick comment</a></b></p><hr />
<p><small>© Edgar Hoo for <a href="http://blog.edgar.im">Edgar&#039;s Blog</a>, 2011. |
<a href="http://blog.edgar.im/article/hello-world.html">Permalink</a> |
<a href="http://blog.edgar.im/article/hello-world.html#comments">One comment</a> |
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
<img src="http://feeds.feedburner.com/~r/edgar-blog/~4/TuN7l7WgbqE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.edgar.im/article/hello-world.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.edgar.im/article/hello-world.html</feedburner:origLink></item>
	</channel>
</rss>

