xufei

Results 32 issues of xufei

# 2015前端组件化框架之路 #1. 为什么组件化这么难做 Web应用的组件化是一个很复杂的话题。 在大型软件中,组件化是一种共识,它一方面提高了开发效率,另一方面降低了维护成本。但是在Web前端这个领域,并没有很通用的组件模式,因为缺少一个大家都能认同的实现方式,所以很多框架/库都实现了自己的组件化方式。 前端圈最热衷于造轮子了,没有哪个别的领域能出现这么混乱而欣欣向荣的景象。这一方面说明前端领域的创造力很旺盛,另一方面却说明了基础设施是不完善的。 我曾经有过这么一个类比,说明某种编程技术及其生态发展的几个阶段: - 最初的时候人们忙着补全各种API,代表着他们拥有的东西还很匮乏,需要在语言跟基础设施上继续完善 - 然后就开始各种模式,标志他们做的东西逐渐变大变复杂,需要更好的组织了 - 然后就是各类分层MVC,MVP,MVVM之类,可视化开发,自动化测试,团队协同系统等等,说明重视生产效率了,也就是所谓工程化 那么,对比这三个阶段,看看关注这三种东西的人数,觉得Web发展到哪一步了? 细节来说,大概是模块化和组件化标准即将大规模落地(好坏先不论),各类API也大致齐备了,终于看到起飞的希望了,各种框架几年内会有非常强力的洗牌,如果不考虑老旧浏览器的拖累,这个洗牌过程将大大加速,然后才能释放Web前端的产能。 但是我们必须注意到,现在这些即将普及的标准,很多都会给之前的工作带来改变。用工业体系的发展史来对比,前端领域目前正处于蒸汽机发明之前,早期机械(比如《木兰辞》里面的机杼,主要是动力与材料比较原始)已经普及的这么一个阶段。 所以,从这个角度看,很多框架/库是会消亡的(专门做模块化的AMD和CMD相关库,专注于标准化DOM选择器铺垫的某些库),一些则必须进行革新,还有一些受的影响会比较小(数据可视化等相关方向),可以有机会沿着自己的方向继续演进。 #2. 标准的变革 对于这类东西来说,能获得广泛群众基础的关键在于:对将来的标准有怎样的迎合程度。对前端编程方式可能造成重大影响的标准有这些: - module - Web Components - class - observe...

blog

## 视图模型的层次 ### 嵌套作用域的数据继承 在Angular中,存在作用域的继承。所谓作用域的继承,是指:如果两个视图有包含关系,内层视图对应的作用域可以共享外层视图作用域的数据。比如说: ``` HTML ``` ``` JavaScript var app = angular.module("test", []); app.controller("OuterCtrl", function ($scope) { $scope.a = 1; }); app.controller("InnerCtrl", function ($scope) { $scope.b = 100;...

# 企业文化与价值观 ### 给新员工的一封信 这个话题其实我早就想写了,刚好最近在跟一些学生接触,而且很快有个应届生徒弟要入职了,想到了当初的自己,所以觉得打算谈谈这些年的一些感悟,希望能有所帮助。 我刚工作的时候,对公司非常热爱,热爱到偏激的程度,比如说觉得竞争对手公司毫无优点,比如每次看到公司的负面评价,都忍不住想出来反驳,甚至能为了这些事情跟多年的老同学争得面红耳赤。 多年之后回头看这一切,会为自己当时的单纯感动,也觉得挺傻的,反思之后,会用它跟另外一件事情作比较,那就是恋爱。 工作跟恋爱,真的是两件非常相似的事情,当我们开始跟一个人好,总会忽视对方的一切缺点,把优点无限放大,然后相处着相处着,好像忽然就发现对方怎么冒出这么多缺点,有时候忍不住说出来,会惹对方很不高兴,为什么呢,因为从他的角度,从未改变过,一直是这样的,为什么之前你不说,过了一阵反而不能容忍了呢? 这个是一种心理反应,体现的是预期与现实的偏差。我们一开始的时候,总是倾向于有一个完美的预期,然后逐渐发现不相符,当这些累积到超过容忍度的时候,就会爆发。 我看到很多人毕业的时候都会对第一家公司充满期待,但这个期待真的有些满,一方面源自对美好未来的期望,另一方面很可能源自企业的误导。这个事情其实不能怪企业,因为就算谈恋爱,你基本上也不可能上来就跟人家说:我先跟你说下我缺点,12345,等你说完人早跑了。企业招聘的时候显然也挑好的说,比如工资没人家高,就说但是我们加班少啊,比如加班也多,就说但是能学到东西啊,总之肯定是充满优点的,涉世未深的大学生们很可能就全信了。 但不巧这个新员工干了一阵,怎么感觉钱少事多离家远,每天干的还重复劳动,好像哪里不对啊?这时候问题就来了,真正的伤害,这种伤害很可怕,第一份工作跟初恋在心理上的重要度是同样的。受这一次伤,可能永远都痛。 这事,我觉得负责招聘的同事有必要深思,有些缺点,如实说出来会比较好,从长远来看,隐瞒一些事实的后果很严重,不如刚开始就诚恳一些。 现在我看到一些新员工跟自己之前的同学争吵,说自己公司好,对方公司是垃圾,就仿佛看到当年的我。我是过来人了,觉得这事真没必要。 每个公司有自己的企业文化,所谓企业文化,是因为一些做事方式而导致的微小差异,并不是真有那么大,就好比你是射手座,书上说射手座很热爱自由,你觉得说得很对,就信了这个,好像别人就不热爱自由似的。然后你因为有这个心理暗示,就更加显得热爱自由,然后又反过来觉得星座这东西真有道理啊。 对待企业文化,我觉得应这么看: - 首先,人性是最高准则,所谓人性,莫过于真善美。 - 在此基础上,可以有小的侧重点,比如华为侧重奋斗,中兴讲究奉献。 如果你冷静下来看看一些公司的企业文化,会发现基本都只是细节差异,因为没有谁会说自己是邪恶的。那既然都是好话,整体来说,你都可以信,如果懒得去花时间理解它们,可以直接以真善美,还有自己内心的喜好为准。 所以现在我看企业文化之类的培训,有时候会摇头笑笑,一方面是因为老油条了,你说的那些我也会,而且说不定比你说得还好,另一方面,既然我接受你,说明我要么认同你的优点,要么不介意你的缺点。 我现在倾向于这么对待企业文化: 如果能接受一家公司的氛围,那就加入。如果不能接受,就离开。 如果觉得值得改进,也有两个选择:等别人来推动,自己来推动。 我见过很多人,不停抱怨公司的各种缺点,但是一不离职,二不想办法改进,我觉得这挺奇怪的。很多时候改进没有那么难,我打个比方,你觉得公司的某个地砖不平,不好走,不找人反馈,然后每天都要吐槽一下,其实说不定就是别人没发现,你跟他一说,他去看了发现果然这样,两分钟就给摆平了。 有时候,还会有人把这样的问题上升成对这个企业的恨,好像企业是故意造出这些小问题,特意为了让员工没有好心情干活,我倾向于认为老板们不会这么蠢,有些问题他不知道而已。 人生在世,想找完全合乎自己心意的伴侣或者环境基本不可能,只有两条路可以选,一是降低预期,二是帮助对方改进。这两者都是改善自己生存状况的好方式。 再说说如何选择环境吧。我承认不同企业的环境确实存在差异,但这不是根本问题。企业对人的影响,远不如所在团队对人的影响大,最直接相处的人才会对自己造成最深刻的影响。就好比上学,一个人的成长过程,至少有大半取决于父母和自身,然后才轮到学校的同学和老师。所以选择工作的时候,也不一定太看重企业的大环境,如果有机会挑选到出色的上级和同事,那才是事业中最大的助力。 我有时候反思自己,觉得过于爱谈正能量,俗称鸡汤。这东西也没什么不对,总比散布负能量要好些,是不是?但我现在很害怕这些话被太单纯的人看见,会让他们觉得世界特别美好,这样,碰到挫折的时候伤得格外重。 这事情也有一个道理,叫做:已所欲,勿施于人。这世上当然是有一些人,或者因为理想,或者因为利益,会期望别人跟自己有相似的行为准则,但这一不小心就能变成道德绑架,我之前干过不少,很惭愧。...

# Angular沉思录 接触AngularJS已经两年多了,时常问自己一些问题,如果是我实现它,会在哪些方面选择跟它相同的道路,哪些方面不同。为此,记录了一些思考,给自己回顾,也供他人参考。 初步大致有以下几个方面: - 数据双向绑定 - 视图模型的继承关系 - 模块和依赖注入的设计 - 待定 ## 数据的双向绑定 Angular实现了双向绑定机制。所谓的双向绑定,无非是从界面的操作能实时反映到数据,数据的变更能实时展现到界面。 一个最简单的示例就是这样: ``` HTML increase ``` ``` JavaScript function CounterCtrl($scope) { $scope.counter = 1; } ```...

这是对知乎上一个问题的回答:https://www.zhihu.com/question/39943474/answer/83905933 我们学一个东西,通常两个目的: - 为了解决现有的问题 - 为了解决将来可能会有的问题 所以,在学这些东西之前,先必须了解,它们是用来解决什么问题的。 Angular,React,Vue,这三者其实面对的是同一个领域,那就是Web应用,什么是Web应用呢,我之前有一篇大致讲了:构建单页Web应用 · Issue #5 · xufei/blog · GitHub 这三者中,Angular的适用领域相对窄一些,React可以拓展到服务端,移动端Native部分,而Vue因为比较轻量,还能用于业务场景非常轻的页面中。 在Web应用中,我们需要解决的问题可以归纳为三类: - 状态 - 组织 - 效率 1. 状态 什么是状态? 在一个业务界面中,我们可能会根据某些数据去生成一块界面,然后通过界面上的某些操作,改变一些数据,从而影响界面的另外一些部分。 这里面就存在两种关系,一种是从数据到界面,一种是从界面到数据。能够描述界面当前状况的数据,就可以被称为状态。 如果不对状态作抽象,很可能会导致逻辑的混乱,比如说,一个地方点了,要改多个地方,这种代码直接写,很容易写乱的,所以,不同的框架采用不同的方式进行了处理。 比如说MVVM流的Angular和Vue,还有Avalon,Regular,Knockout,都是走的这一流派,通过类似模板的语法,描述界面状态与数据的绑定关系,然后通过内部转换,把这个结构建立起来,当界面发生变化的时候,按照配置规则去更新相应的数据,然后,再根据配置好的规则去,从数据更新界面状态。...

# 今年搞的一些活动的意图 今年我发起了三件事: - 针对南京地区在校大学生的读书赞助 - 公司内部前端协会的成立,每周定期的技术交流,每次赞助四本书抽奖,带公司的前端同事到别的城市听技术分享等等 - 把苏宁的前端协会推进到大学校园里 很高兴在年底的时候,能看到这三个方向都有所进展,这三个事情都是我一个长期规划的具体实现,那就是:促进南京地区的前端生态圈。 目前,全国前端技术精英最集中的是三个地区:北京周围,长三角,珠三角。其中,南京位居长三角的一端,但是前端氛围要远远差于上海和杭州,甚至可能连武汉、成都都不如,原因在哪里呢? 我经常拿杭州跟南京比较,两个城市,规模相似,地位相当,教育程度也差不多,甚至可能南京的高校还略强些,但为什么不光前端,整个互联网的氛围都是杭州秒杀南京呢? 我看过一些文章分析两个城市,甚至两个省份人民性格的差异,说不出有没有道理,但问题总要想办法解决,我一直坚信事在人为,有些事情去推动一下,可能比想象的结果要好很多。 所以我搞了一个长期的规划,意图促进南京地区前端圈子的建立。对于生态来讲,首先要有规模,规模就是人,人从哪里来?南京有这么丰富的高校资源,如果能加以引导,应该会对整个城市的技术生态有很大的正向影响,所以从我的长久目标来看,一定要面对大学生。 所以上半年我发起了前端读书活动,这个事情我是以比较粗放的方式来搞的,因为个人精力有限,花钱是小事,没法拿出太多时间来,所以就这样,断断续续也有不少学生参与,整体感觉还可以。 然后就开始考虑以企业的名义跟学校技术社团合作,但面临的问题是我们公司内部都没有技术团体,很松散,这事情就很难办,所以又花了半年时间,整合公司内部的同行员工,成立了前端技术协会,自己作了几次大分享,然后每周形成了固定的交流,虽然说协会内部还有不稳定因素,但总算有组织了,到近期,条件终于比较成熟了,正好有两个学校的学生社团联系我,这事情也就搞起来了。 事情发展到现在,终于真正起步了,整个这个过程的效率不算高,很有改进余地,但实在没有更多精力投入了,这些都不在本职工作内,很花时间,只能保持这种状态。 这时候再回头看做的这三件事,都是有人觉得效果不一定好的,比如说,如果有兴趣的人,根本不用去推进,自己会很主动。但我更大的意图并不是聚集这些本来就有兴趣的人,因为这些人真的太少了,我想要推动的是那些观望的人。 我一直认为,人分为三种。第一种积极主动,有理想或者激情,大约占10%,另一种就是自暴自弃,负能量爆棚,也算10%,那剩下80%是什么呢,是普通人。 普通人有一个特点,他没有很强的愿望去做某件事,但如果因为某些原因他开始做了,也能习惯。我今年思考了很多,觉得对于普通的人,他有两种心理,一种是服从强权,一种是从众,而且很容易就能形成习惯。 强权很好理解,怎么理解从众呢?我打个比方,在大学宿舍里,很多人可以打牌也可以不打牌,很多时候他没想打,这时候来了个人说,打牌打牌,至少一半的人就会想,反正也没坏处,那就打吧。如果那人再坚持一下,原先不太想打的也可能参与了。 所以我想利用的就是这种心理,把这个中间的人吸引一些过来。我并不期望每个参与赠书活动的大学生都会看书,更不期望每个参加社团交流的人都能学下去,只是希望他们中的一部分,比如说之前从来没想过学前端,自己根本不会主动去看,但我送了一本书到桌上,有时候无聊,翻开看看到底讲点什么,说不定就觉得挺好玩,然后就搞下去了呢?或者原先不知道这是干什么的,随便跟人来社团听听,觉得讲得还挺有意思的,也就自己开始跟着瞎折腾了呢? 我所期待的,也就是通过这类方式,能增加愿意参与前端方向的人数,任何一项技术能够发展,都离不开一个群体,靠几个人是没法提高的,必须有很多人都参与,每人有点想法,从交流的过程中,大家才都能受益。 明年,我们将有更多这方面的规划,也期望业内同仁能多多指教,更希望有越来越多的南京地区的高校和企业参与这些活动中来,把南京地区的互联网氛围搞活。至于说这些学生,将来是不是来了苏宁,或者是去了别的地方,我觉得都不是坏事,楚人失之,楚人得之,为什么一定要那么狭隘? 也感谢这一年里家人对我的容忍,因为花了很多晚上和周末的时间搞这些事,而且差不多送出去了一万多的书。但我相信,这一切是会有回报的,就像下棋,能把一盘棋先下活,后面的机会就会更多。理想当然要有,说不定就实现了呢?

# 浴火重生的Angular Angular团队近期公布了他们对2.0版本的一些考虑,很详尽,很诚恳,我读了好几遍,觉得有必要写点东西。 对于一个运行在浏览器中的JavaScript框架而言,最喜欢什么,最害怕什么?是标准的变动。那么,放眼最新的这些标准,有哪些因素会对框架产生影响呢? - module - Web Components - observe - promise 这几点,我是按照影响程度从大到小排列的。下面逐条来说: ### module 早期的JavaScript在模块定义方面基本没有约束,但作为框架来说,不按照某种约定的方式去写代码,就会导致一盘散沙,所以各家都自己搞一套,大部分还是各不兼容的,这是历史原因造成的,不能怪罪这些框架。最近几年,为了解决这些问题,人们又发明了AMD,CMD,以及各种配套库和工程库。好不容易有些框架向它们靠拢了,可是module又来了。 这真是没完。我知道很多人是对module有意见的,我自己也觉得有些别扭,但我坚信一个道理:有一个可用但是稍微别扭的标准,比没有标准要好得多。所以,不管怎样,既然他来了,就得想办法往上靠。不靠拢标准的后果是什么?非常严重,因为现在的Web是加速发展的,浏览器只要过了一个升级瓶颈,后面的发展快得出奇。不要看现在还有这么多老旧浏览器,很可能你睡一觉起来突然发现已经基本没人用了,到那时候,不紧跟标准的框架就很惨了,瞬间就边缘化了。 我们来看看Angular原先的module设计,如果是在五年前,它刚起步的时候看,可能觉得还可以,现在再看,问题就比较多了。Angular现有版本的module,其实跟我们在ES中看到的module不是一个概念,更像C#里面的namespace,它的各种controller,service,factory才是真的模块。 我认为现有版本的这块,有几个不好的地方: - 现有的module实际上毫无意义,根本不能起约束作用。 - 从API的角度强制区分模块职责是没有必要的,比如说,service和factory的区别在哪里?仅仅在于返回与封装的方式不同,其实是可以通用的,所以只需一种工厂方法就可以了,用户愿意返回什么就返回什么,他自己通过命名来区分这个模块的职责。 - 没考虑模块的动态加载。这是Angular目前版本最大的设计问题,对于大型应用来说,很致命,所以目前大家都是通过各种黑魔法来解决这个问题。 所以,Angular 2.0中,把这一块彻底改变了,使用ES6的module来定义模块,也考虑了动态加载的需求。变动很大,很多人有意见,但我是支持他们的。这件事不得不做,即使现在不做,将来也还是要做。毛主席教导我们:革命不彻底,劳动人民就要吃两茬苦,受两茬罪。在现在这个时代,如果还继续用非标准的模块API,基本等于找死,所以它需要改变。 ### Web...

# Web应用的组件化(二) ## 管控平台 在上一篇中我们提到了组件化的大致思路,这一篇主要讲述在这么做之后,我们需要哪些外围手段去管控整个开发过程。从各种角度看,面对较大规模前端开发团队,都有必要建立这么一个开发阶段的协作平台。 在这个平台上,我们要做哪些事情呢? #1. HTML片段 我们为什么要管理HTML片段?因为有界面要用它们,当这些片段多了之后,需要有个地方来管理起来,可以检索、预览它们,还能看到大致描述。 这应该是整个环节中一个相对很简单的东西,照理说,有目录结构,然后剩下的就是单个的HTML片段文件了,这就可以解决存储和检索的问题了,但我们还要考虑更多。 已有的HTML片段,如何被使用呢?这肯定是一种类似include的方式,通过某种特殊标签(不管是前端还是后端的方式)把这些片段引用进来,这时候就有了第一个问题: 假设有界面A和界面B同时引用了片段C,在某个开发人员修改片段C内容的时候,他如何得知将会影响到界面A和B呢?一个比较勉强的方式是全项目查找,但这在很多情况下是不够的。 如果我们的HTML片段是作为独立的公共库存在的,它已经不能通过项目内查找去解决这一问题了,因为不管A还是B,只要他不处于片段C的项目空间,就无从追寻。 这时候很多人会问两个问题: 1. 跨项目的界面片段重用,意义在哪里? 如果我们的产品是针对一个小领域,它的复杂度根本不需要划分多个项目部分来协作完成。设想场景是面对很大的行业,各项目都是子产品,将来可能是其中若干个联合部署,这时候,保持其中的一致性是非常重要的。比如我们有个基本配置界面,在多个子产品中都要用,如果各自开发一个,其操作风格很可能就是不一致的,给人的印象就是不专业。所以会需要把常见的界面片段都归集起来,供业务方挑选使用。 2. 修改C,只提供说明,但是不通知A和B,不实时更新他们的版本,然后自行决定怎样升级,如何? 这会有一个问题,每次有小功能升级的时候,代码是最容易同步合并的,所以才会有“持续集成”这个概念,如果是一直伴随升级,总要比隔一个大阶段才升级好,升级成本应尽量分摊到平时,就像农妇养小猪,小猪每天长一点,每天都抱来抱去,不觉得吃力,即使长大了也还能抱得动。 现在问题就很明确了,一定要有一种方式来把这个依赖关系管理起来,很显然,已有的版本库是肯定管不了这些的,所以只能在外围做一些处理。 我们建立一个管理平台,除了管理实体文件的版本,还管它们之间的关系。具体这个关系如何收集整理,有两种方式:手动配置,代码分析。 手动配置是比较土的方式,开发人员每提交一个文件,就去这系统上手动配置它的依赖关系。代码分析的话,要在每次提交文件的时候解析文件的包含规则,找出确切的文件。这两者各有利弊,前者比较笨,但容易做,后者对代码格式的要求比较高,要考虑的情况较多。 我们的界面往往不是那么简单,HTML片段也可能有层次的,举例来说: 界面A里面包含了片段B,但是片段B自身又包含了片段C,所以这个依赖关系也是有层级的,需要在设计的时候一并考虑。 #2. JavaScript模块 JavaScript代码的管理,比HTML片段的状况好一些,因为业界很多这方面的解决方案。但它们还是没有解决当依赖项产生变更的时候反向通知的问题。 所以我们还是得像HTML片段一样,把它们的依赖关系都管理到平台里。于是,每个JavaScript模块都显式配置了自己所依赖的其他模块,通过这种单向关系,形成了一套完整的视图。 在JavaScript模块的代码实现中,我们是不提倡直接写依赖关系的。很多通用规范,比如AMD,往往建议我们这样写模块:...

blog

## 作用域与事件 学习Angular,首先要理解其作用域机制。 Angular应用是分层的,主要有三个层面:视图,模型,视图模型。其中,视图很好理解,就是直接可见的界面,模型就是数据,那么视图模型是什么呢?是一种把数据包装给视图调用的东西。 所谓作用域,也就是视图模型中的一个概念。 ### 根作用域 在第一章中,有这么一个很简单的数据绑定例子: ``` HTML {{rootA}} ``` 当时我们解释过,这个例子能够运行的的原因是,它的rootA变量被创建在根作用域上。每个Angular应用默认有一个根作用域,也就是说,如果用户未指定自己的控制器,变量就是直接挂在这个层级上的。 作用域在一个Angular应用中是以树的形状体现的,根作用域位于最顶层,从它往下挂着各级作用域。每一级作用域上面挂着变量和方法,供所属的视图调用。 如果想要在代码中显式使用根作用域,可以注入$rootScope。 怎么证实刚才的例子中,$rootScope确实存在,而且变量真的在它上面呢?我们来写个代码: ``` JavaScript function RootService($rootScope) { $rootScope.$watch("rootA", function(newVal) { alert(newVal); }); } ``` 这时候我们可以看到,这段代码并未跟界面产生任何关系,但里面的监控表达式确实生效了,也就是说,观测到了根作用域上rootA的变更,说明有人给它赋值了。 ###...

ng-tutor

前一段时间,我写了两篇文章,一篇是对目前前端主流视图框架的思考:#37,一篇是深入使用RxJS控制复杂业务逻辑的:#38,在这两篇中,我分别提到: - 期望在复杂业务逻辑方面使用RxJS,更好地进行抽象,但是视图上使用轻量MVVM以达到快速开发的目的。 - 目前VueJS中,如果要结合RxJS,可能需要手动订阅和取消订阅,写起来还是没有CycleJS方便。 最近,VueJS社区升级了vue-rx这个库,实现了比较方便地把VueJS和RxJS结合的能力。 我们来详细了解一下。 ## 在视图上绑定Observable VueJS本身不是基于RxJS这一套理念构建的,如果不借助任何辅助的东西,可能我们会需要干这么一些事情: - 手动订阅某些Observable,在observer里面,把数据设置到Vue的data上 - 在视图销毁的时候,手动取消订阅 在业务开发中,我们最常用的是绑定简单的Observable,在vue-rx中,这个需求被很轻松地满足了。 与早期版本不同,vue-rx 2.0在Vue实例上添加了一个subscriptions属性,里面放置各种待绑定的Observable,用的时候类似data。 比如,我们可以这么用它: `rx-simple.vue` ``` Single Value {{single$}} Array {{item}} {{item}} Interval {{interval$}} High-order {{high$}}...