#BackboneConf2012 How to Argue about Javascript by Andrew Dupont

Backbone Conf 2012

有幸去美国波士顿参加了2012年的 Backbone.js Conference,见到了coffeescriptunderscore.js 还有 backbone.js 的作者 Jeremy Ashkenas。会议内容围绕前端MVWTF和社区进行了很多有趣的讨论,有很多有价值的观点。我希望在这里面与大家分享我从里面学到的东西。

这系列博客其实是我整理的会议笔记的汇总,是我对每个话题中比较有印象或者比较重要的内容的摘抄,这些观点几乎都不是我的,我仅作为一个传声者。我是希望把所有的Credit交给演讲者自己,我最多只是一个翻译者,碰巧幸运的在现场。Backbone.js Conference和O’Reilly的Fluent Conference 碰巧同时进行,#BackboneConf 更加草根,但是也更有观点。

How to Argue about Javascript by Andrew Dupont

Andrew Dupont

Links

Notes

Andrew说话比较慢(尤其是没有预先准备的时候),但是他的语言很睿智。他的话题也很睿智,讲的不是具体的框架或者技术,而是软技巧“如何争论?”。他讨论了如何好好的辩论,而如何辩论是不好的。

核心的事件就是社区内火热的Semicolon问题~

How not to argue about semicolons?

  • Our arguments should be purposeful

要有目的,就是说为了解决实际的问题。比如科学研究符合这点,不过很多政治争论不符合这点(政见之争是狗屁?)。他引用了Carl Sagan说的一段话,大意是科学家比较可能会放弃自己的立场并被说服,但是政治和宗教之争很难看到放下武器站到对方一边的场景。

这些是常见的一些场景:

  • “Whoe the hell are you?” – 你微不足道
  • “Whre do you get off censoring me, you fascist?” – 你凭什么管我,你个法西斯
  • Motives for having a code argument:那么我们为什么在代码问题上争论呢?

其实不应该是为了显摆你自己,也不应该为了说服别人认同你的想法。

争论的目的应该是更好的了解你们争论的主题

有一本很有名的书叫”Getting to yess”,副标题是Negotiating agreement without giving in。

An argument has 3 goals:

  • It should produce a wise agreement, if possible 应该达成聪明的一致
  • It should be efficient 有效率
  • It should not damage the relationship between parties 不破坏各方的关系

Tactics for arguments: 争论的战术

  • Separate the people from the problem 就事不对人,必须区分问题的目的(本质)和你对这件事的情感因素
  • Focus on interests, not positions 注重共同的利益,而不是自己的立场(位置)
  • Invent options for mutual gain 创造一些方案来达到共同受益
  • Insist on objective criteria 只坚持客观的条件(如标准、benchmarks)

这个例子很逗,分号之争来自github上面的一个bug。有人报了bug,然后 @fat 说这不是他代码的bug,而是 JSMIN 的bug。然后 douglas crockford大神 蹦出来说这不是 JSMIN 的bug,而是 @fat 对js分隔符理解有问题(其实不完全是),然后 @fat 就反驳说我就这样写你怎么地吧?

zzzzing! 这梁子就算是结上了!

另外一个例子是Selector引擎战争,这源自moo.tools作者写的一个benchmark,职责JQuery的selector引擎比较弱,因为它的选择器在这个benchmark的很多场景下都是比较慢的。

然后John Resig就写了一篇犀利的博客 “Selectors that people actually use“,职责这个benchmark里面的很多场景并非人类常用……

那我们应该怎样办呢?我们应该以愿意被说服的态度去讨论,思考对方为什么持不同的简介,考虑品味的不同,考虑情绪的问题。

他举了John的另外一个例子,他如何回答 “JQuery steals code” 和 “JQuery hates developers, love companies” 这两个问题。他的博客犀利、幽默,是解决这种问题的一个典范。他没有直接争论,而是用有趣的方式去化解自己的被动。

后面回到例子的主线,就是Bootstrap是否应该为了 JSMIN 去增加一个分号呢?库的作者是否应该为了 JSMIN 兼容性去做一些让步呢?还是 JSMIN 应该主动改变(Crockford 觉得那样做很没品)。

有趣的句子:

“People who don’t use semicolons are Javascript hipsters.”

“No, people who are fanatical about semicolons are just spreading FUD.”

“@fat is being a jackass and a bad project steward.”

“No, people like you are bitching about a library they got for free.”

“Semicolon or not, that line should still be rewritten.”

“JSMin sucks anyway. People should use some other minifier.”

“Who cares about minification? Everyone’s got a fast connection now.”

争论愈演愈烈,慢慢变成各种人身攻击和开玩笑,很多人抱怨这个ticket不停的给他发邮件……

最搞笑的是 @fat 本人在中间留言,新版的Bootstrap已经修正了这个问题了……后面还是继续 shit storm

但是后面还是各种人身攻击……

作者用了一个特别贴切的形容词”Shit-storm”!

这说明跑题了,如何不跑题呢?

要温和一些(和谐),be nice! 说话要精确,不要扫射……

作者举了一些委婉的表达的例子……很委婉。

javascript社区还有很多例子

  • Ember vs. Backbone
  • Mico-frameworks
  • Coffeescript!
  • Douglas Crockford vs. the world 这个是开玩笑的

总的来说,社区里面争论真的是一个非常重要的事情,避免Shit-storm的发生对社区有益。

知乎里面就有这个争论的延伸,虽然这里没有脏字,但是大部分人也一样是被卷入这个争论……

我的回答:

加与不加是风格问题,风格争议不需要有个定论。关键的问题在于如何“争论”,处理好冲突,学会组织语言减少争议是最重要的。因为分号问题在社区内部造成了很多况日持久的口水战,这些口水战是社区的损失……因为大家在这个时候可以写更多的代码带来更多的功能。

#BackboneConf2012 Ember.js by Yehuda Katz

Backbone Conf 2012

有幸去美国波士顿参加了2012年的 Backbone.js Conference,见到了coffeescriptunderscore.js 还有 backbone.js 的作者 Jeremy Ashkenas。会议内容围绕前端MVWTF和社区进行了很多有趣的讨论,有很多有价值的观点。我希望在这里面与大家分享我从里面学到的东西。

这系列博客其实是我整理的会议笔记的汇总,是我对每个话题中比较有印象或者比较重要的内容的摘抄,这些观点几乎都不是我的,我仅作为一个传声者。我是希望把所有的Credit交给演讲者自己,我最多只是一个翻译者,碰巧幸运的在现场。Backbone.js Conference和O’Reilly的Fluent Conference 碰巧同时进行,#BackboneConf 更加草根,但是也更有观点。

Ember.js by Yehuda Katz

Yehuda Katz

Links

Notes

Ember.js的主力开发者和鼓吹者是Yehuda Katz,这个框架来自于他们团队所咨询的项目。所以这也是由实际需求催生的一个项目。

Ember.js expectations

  • bidirectional data binding, it’s special
  • View hierarchy
  • Structure and Widgets
  • Routing

Ember’s Bindings are backed into the object model.

bindings are always async. It guarantees you the ability to make all necessary changes before side-effects occur.

它很智能的解决了单个属性changes造成的event雪崩。若干Model set只会集中触发一次UI update。Guarantees a single DOM update per turn in the browser’s event loop.

它的Template组合方式保证子template的渲染只有一次Dom update。

它的View hierarchy也就是CompositeView处理了子View的状态清理(双向unbind,释放资源),并且提供了一些Lifecycle events(很有价值)。

Template的渲染过程隐含了Collection和Model的事件绑定,Template里面的action可以在Router触发事件并且可以生成对应的url。

Ember.js的特点就是用黑魔法(black magic,注:这是我说的,是我的偏见 ;-D)帮你默认做了很多事情,作者管这个叫“Does the right thing by default”,这是一个双刃剑。但是对于有很多雷同的页面和功能的项目来说它可以保证write less do more,并且平均的代码质量会提高(因为复杂逻辑完全被框架所封装好了)。

Backbone.js的一个重要买点是View的Stateless,而ember.js则通过Routing主动的负担起了State Management的责任。Router里面定义了系统的各种State,用户点击action或者通过URL跳转实际上是改变了状态机的状态,router定义了这些状态和状态转换。因为UI状态机实际上是一个非常复杂的建模方式,因为状态的转换组合可以让系统处于很多复杂和混乱的情境中,当然ember.js这样做也是有理由的,它的好处包括logging、对生产应用进行debugging,避免不可能的情况(通过定义所有可能的情况!)。

对于状态机这个表述,Yehuda在现场被很多“大牛”质疑了,获得了不少的嘘声。不过这的确是解决非常复杂的问题的一种标准的解决方法,但是由于这种分析方式本身(定义状态,把不同的状态正交的解开)有很大的难度,所以它有可能会让你陷身泥潭。这就是很多注重简单的MVWTF框架会选择不去管理状态,而选择Stateless的原因。

#BackboneConf2012 Keynote for BackboneConf by Jeremy Ashkenas

Backbone Conf 2012

有幸去美国波士顿参加了2012年的 Backbone.js Conference,见到了coffeescriptunderscore.js 还有 backbone.js 的作者 Jeremy Ashkenas。会议内容围绕前端MVWTF和社区进行了很多有趣的讨论,有很多有价值的观点。我希望在这里面与大家分享我从里面学到的东西。

这系列博客其实是我整理的会议笔记的汇总,是我对每个话题中比较有印象或者比较重要的内容的摘抄,这些观点几乎都不是我的,我仅作为一个传声者。我是希望把所有的Credit交给演讲者自己,我最多只是一个翻译者,碰巧幸运的在现场。Backbone.js Conference和O’Reilly的Fluent Conference 碰巧同时进行,#BackboneConf 更加草根,但是也更有观点。

Keynote for BackboneConf by Jeremy Ashkenas

The keynote

Links

Notes

  • Backbone.js成长的非常快,只用了1.5年就在社区内引起了巨大的反响
  • Backbone是来自真实的项目,满足真实的需求,这个框架只是一个副产品
  • Backbone.js是抽出DocumentCloud项目可复用的部分的产物
  • Backbone.js的用户很大牌

Backbone.js是一个small、simple、flexible的框架,所以没有典型的Backbone应用,我们现在看到的例子只是冰山的一角。

传统的JQuery的一个大的问题就是它面对的是获取文本,更新HTML上的另外一些文本。但是这个过程中我们没有明确的获取和渲染数据模型。

Avoid jQuery hell by getting your state of out of the DOM

因为JQuery更新的Dom本身就是有状态的,所以代码尝尝混杂者状态判断的逻辑,这是很让人头疼的状态。

Model is where your data lives, source of truth for application. UI only knows about the truth in the models. UI can’t conflict with others

数据模型应该表示状态,让UI与状态分离,这样UI之间就不会因为复杂的状态而纠缠不清。

在Backbone.js里面,我们修改Model的状态。而其它的组件监听Model的事件。

ClientSide的collection一般是整体Model的repository的一个子集。Model是个体,而collection是集合。他们是保持客户端状态的基础。Underscore.js用来访问Model和Collection,它是Backbone.js的魅力的体现。

Ashkenas演示了他们使用namespace,把系统中所有的Model和View实例全部都放在一个树型数据结构上,可以看到View的实例一般是绑定在相应的Collection和Model下面。这个树形数据结构保存了客户端的所有状态和实例,对于debug非常有利。View放在Collection和Model下面是因为View是无状态的(它依附于相应的Collection和Model的状态)。

Changes

一般的模式是Model被set后View就re-render,View会监听change事件。Model和Collection的save的语义是将变化传递到服务器(持久化),而set只是修改状态并触发change。

Model和Collection初始化的时候可能需要逐层载入,这个时候可能会触发多次change,可以使用参数{silent: true}。它是专门应对触发change的中间状态而设计的,当需要触发View的re-render时再trigger change事件。这样的设计可以保证View是完全无状态的。

有人问客户端Model会有一些对服务器端没有意义的属性,如selected表示一个模型是否是被选中的状态,这可以么?
因为Model是用来保存系统状态的,所以这些状态属性就应该放在Model里面。

View的更新是应该使用乐观模式还是悲观模式呢?(是否等待状态保存到服务器后再更新UI)。
这个要看场景,Instagram就做了很多这样的trick。避免状态不一致是最重要的,所以对于不太可靠的更新需要使用悲观方式。

Model之间的关系如何传递?Model的属性是否可以是collection。
可以,通过Model和它的属性间的event proxy传递event。(第二天的SuperModel,还有其它解决方案,可以用声明的方式绑定Model和sub models之间的关系,自动proxy event)

change event的listener可以通过this.get(‘prop’)和this.previous(‘prop’)来获取修改的属性的变化情况。

Views

Views should be stateless!!!

  • View is stateless if it always has a dom element at all times
  • Did my view render in a particular mode when it doesn’t exist? No, elem is always there and events are always delegated

View在它被初始化的时候它的element就应该已经存在,这样它的render和re-render就不会依赖于其它先置条件,从而保持stateless。

Backbone.js的哲学Philosophy

Take the truth out of the DOM.

  • So the only truth is the model 😀

Intentionally minimal

  • Small, Simple, Flexible

Resited Router for a while. Jeremy still thinks Router may be overreaching

Tries to be driven by use cases, not gospel. If you open ticket on GitHub without use cases, you’ll get ignored

Is Backbone.js MVC, MV+, MVP?

  • It’s MVWhatever
  • Important thing is that UI and Models are the common denominator. Build interesting UI without breaking app and build interesting business logic without breaking UI.
  • 最重要的分离是Model和View的分离,Model是保持状态的核心,View是无状态的

Statelessness

  • Backbone doesn’t do it for you
  • Exponential states of UI should be avoided. Don’t enumerate every state
    • UI因为是一种组合视图,所以它的状态是指数式增长的,所以要避免枚举UI的状态组合,保证UI是无状态的
  • Models contain state, UI listens to models, but UI doesn’t care about what is going on with rest of app

Other things discussed in this session

  • 在客户端和服务器端共享代码?Jeremy觉得这好像不是个好主意,但是在服务器和客户端建立一种Event传递机制似乎是一个可以考虑的方向。
  • 大家公认View的unload是一个痛点:大家发现View的初始化往往比较容易,但是View在不活跃或者需要被替换掉的时候如何unbind事件,如何处理已经渲染过的Dom,解除所有其它的双向依赖是个问题。因为View和子View的生命周期和他们的依赖关系目前还没有被建模,所以没有统一的解决方法。Jeremy透露目前他们的解决方法是通过namespace下面的遍历来unbind所有的sub-view,这种方法在不是非常复杂的情况下是可行的。不过由于这个公认痛点的存在,社区内大家都在尝试找到一种比较通用的简单解决方法。