Open Jinjiang opened 9 years ago
我们已经在内部版本实现了简单的服务端渲染,有了这个东西会怎样呢? 一旦我们可以在服务端直接渲染出界面的 JSON 结构,客户端就可以绕过 JavaScript 解析过程,直接根据 JSON 结构把界面渲染出来。与其对应的逻辑控制稍后也会初始化好,并和界面效果最终保持同步,但在整个过程中,首屏加载的时间会进一步缩短。而且,更令人兴奋的是,如果当前界面刚好没有交互逻辑,甚至后期的 JavaScript 也不需要参与了,这是一条更短的链路!
跟我自己原本想做的东西基本一致-->通过JSON
生成页面。只不过weex
在生成JSON之前加多了个transformer
,其实不止是 webcomponents
,换成其他也是可以进行转换,因为思路已经在那里了。~而这个核心的思想一样可以用来构建pc页面,相当于打造了一个积木系统
去快速搭建专题页面了。~
只不过目前我们大多数页面仔还是面多浏览器比较多而非native
,weex
可能会引起前端开发者对native
的青睐,也可能未必。~
在移动端浏览器上的表现能否更上一层楼?这让人很期待。 很好,很强大。~
nice
效率好高 先占坑 等下来读
持续关注
终于知道@Jinjiang (@勾股) 为啥之前一直在研究webcomponent & vue.js了~ :+1:
Model -- (js)transformer--- H5 view | | (native)transfromer | | interactive (interface) native view ----------------
Model (component way) transformer ( v.js or native)
transformer很好,解决了一些痛点。站在了vue.js
, react.js
的肩膀上,不过还是挺好的。
这些思路真是值得学习!太棒了。
这篇看不懂的干货多起来了……期待。
强大
我们希望移动客户端可以具备动态发布的能力同时不失良好的性能和体验
这里面有三个关键要素,同时也是 Weex 的侧重点:
我们并不是一个人在战斗,市面上已经有很多非常优秀的技术可供参考和使用,Weex 希望集优秀技术之大成,快速落地,解决业务上“最后一公里”的问题。
另外除了介绍设计初衷,也想强调一下 Weex 不是什么:
是的,这是基于动态性业务需要的考虑,也是工作效率最大化的必然产物
也就是我们所说的“实时/动态部署”:通过 JS 进行描述和控制,把传输体积做到最小,把运算量降到最小,加上配套发布机制
这几个问题统一解答一下。
很多同学也开玩笑说这就是个“vue-native”,对此我没什么可否认的。团队在前期考虑移动端动态性解决方案的时候,包括整个实施过程中,对我们影响最深远的应该就是 React Native 和 Vue.js 了。我们也不介意晒一下这套技术方案背后的“幕后英雄”们:
vue-loader
也是这个思路)呵呵是的,我在准备这套技术方案早期几乎见人就问 MVVM 和 React [偷笑]
可以透露一些心路历程
今年早些时候在 ShenJS 的时候,我自己也有幸和 Vue.js 的作者尤小右当面探讨过这些问题。我记得直接问了他是否对“Vue Native”这样的东西感兴趣,小右说自己的精力会先集中在 Vue 1.0 上,但随后小右提到一个观点:
实际上 Virtual DOM 可以理解为就是一个 AST,如果依赖收集能够和 AST 再结合起来,应该会不错
同时也在之后的一次技术交流的场合跟贺老聊到这件事:
还有一次和达峰聊到 React,我们都看过源码,有一个相同的感受,就是 React 的量级还是有点重,有点“过度实现” (记得原词是 over-implement,R 粉请原谅我这样讲),尤其放到移动端。所以不论是 React.js 还是通过 React Native,我们想达到动态化的目的,都不一定是最好的选择
这些经历都给了我很多信息和思考
再后来,集团很多兄弟团队都在做着各式各样的 React Native 的尝试,看得到大家各自的突破和成绩,也不时看到一些瓶颈和无奈,尤其是体积、性能和可控度上。我不由得思考这样一个问题,就是 React Native 对于“动态化”这件事来说是否是最合适的基础?我们是否可以取其精华,汇集各路优秀的观点和理念,做出一个更合适的“最后一公里”技术方案?
再综合之前的一些想法和周围朋友的鼓励,最后如大家看到的,我在团队提出并实践了现在的这套 Weex 技术方案,并且有机会通过双十一主会场这样的业务得到了检验。
上面一个问题的答复中其实提到了不少,我不太善于也不热衷评价别人,但 Weex 是一个特点鲜明目的很明确的技术方案,而且会继续在这条路上不断走下去,同时 React 和 Vue 也都非常赞!
目前 HTML5 的版本确实都是通过 JavaScript 生成界面的,从 SEO 的角度看是非常不理想的,不过有 2 件事:
还蛮多的,说几个刻骨铭心的
onappear
和 ondisappear
的非标准事件,当元素被滚动到可视区域时,appear
事件会被触发,而滚动出可视区域时,则会触发 disappear
,然后图片可以选择在 appear
的时机完成首次加载,商品分类的横向导航条的“自动定位”功能也是借助每个商品楼层的 appear
和 disappear
事件实现的setTimeout
的,当然这个很好再实现<div>
没什么大不了的,但是在移动端结点数是一个很关键的要素,所以不能滥写容器,能省则省另外也顺便抛一些尚未解决的问题,非常希望得到大家的指点和建议!
我们非常希望乐于开源,和更多人一起分享和共建 (我们已经在刚结束的旧金山 QCon 上宣布了未来开源的打算),现在我们的 native 底层还依赖着很多集团私有的架构和服务,比如基于阿里的图片 CDN 做了加载策略的深度优化,基于阿里的底层网络库做了数据请求的深度优化等等。所以这会有个过程 (如果你迫不及待想体验……机会也是有的,你懂的)
最后还是再次感谢大家的关注,大家提出来的问题我会继续和大家一起探讨
这个大前端的实现思路不得不让人佩服
好激动的样子
等开源再说
淘宝又造了个轮子,希望开源库能走出国门,与国际接轨。
期待开源
阿里之前搞了这么多MVVM框架,终于搞出一个像样的出来了
针对业务场景,将合适的技术整合在一起,形成解决方案,就是创新了,也多亏了有这样的团队支撑
后端渲染服务应该是用phantomJS做的吧
能谈一下研发的各个时间节点么:)
赶紧刘明
前排啃瓜子~
star再看~~
跟目前我们项目开发方式某些地方很相近,组件化的方式,提一个小小的建议,在定义组件绑定数据的时候,
<script>
module.exports = {
data: {
title: 'World'
},
methods: {
foo: function (e) {
this.title = 'V'
}
}
}
</script>
除data、methods属性外,加一个options属性,可能对后期组件的应用场景带来更多的可能。目前我们组件绑定数据是这样的:
<script>
module.exports = {
opts:{
editable:true
},
data: {
title: 'World'
},
actions: {
foo: function (e) {
this.title = 'V'
}
}
}
</script>
大公司自己研究,小公司使用开源就好了,这是要累死程序员的节奏啊。有好多不懂的东西要学习:)
请问如何解决多人协作时 css的命名冲突
<template>
<div>
<img src="http://www.taobao.com/favicon.ico" width="32" height="32" onclick="foo"></img>
<span style="color: red;">Hello{{name}}!</span>
</div>
</template>
<style>
.title {color: red;}
</style>
@stephenzhao 可以看一下vue loader,在编译组件的时候会给相应的dom加上随机属性,并且将所有css选择器也加上了同样的随机属性,以此来解决scope css的问题
React 组件内部采用 js 本身替代了 mustache 这样的“小语言”,有了更大的灵活性。换句话说就是抛弃了 template 这个概念。这个我觉得挺好的。
令人激动的架构!
再补充一些:今天被同时问到了两个问题
- Weex 大量借鉴了 Vue,所以应该叫 Vue-native
- Weex 是顺着 WeApp 一路走过来的 (也是 HTML5、native、服务端三端同事一起搞出来的,但说得像只有前端搞定的一样)
所以,大家谁都觉得不爽,不然我们把这个技术方案的名字改叫 WeApp-Vue-Mustache-Native-*\ 比较合适…… 另外索性W3C没介意这事儿不然名字更长 或者我在前端圈说这是Vue-Native,在大阿里内部说这是WeApp+,然后在美国 QCon 上说这是 Ali-React-Native
(以上玩笑,也算是在起名字这个地方自嘲一下)
也再多说一些
第一,Weex 的 we 开头一个很重要的层面正是为了代表我们是传承了 WeApp 的很多东西,包括 native 技术栈和团队。两个e是因为如果一个e发音就变了,当然这个名字还有其他方面的因素 第二,Weex 在前端 DSL 这个层面是非常接近 Vue 的,但是整套技术方案,前前后后汲取并引入了很多东西,直接用 Vue-native 也不太妥 (事实上 Vue-native 就是我自己早期起的开发代号,后来跟 native 同事聊的越多越觉得也不太妥,之前我们文章里截图都被大家挖出来了这也没什么可否认的) 第三,我们给技术方案起新名字的时候,确实想过起一个 V 开头的名字,讨论细节就不宜多说了 第四,即便没有上面的那些顾虑,Vue 这个名字在我这个脑残粉看来真的是很“神圣”的,带 Vue 字样的这个名字我也不好直接乱用吧,毕竟这从 Vue 的角度看是“在野”的,做得有模有样也许小右觉得不错,做不好把人家牌子都砸了你们说是吧我究竟把名字起成啥样你们能满意呢 - -
另外简单八卦一些我和小右、Weex 团队的事情:)
我个人长期在关注 Vue,也力所能及为 Vue 做些布道和文档的工作,也比较早的时候私下和小右交流过把 native 化的想法,这些讨论现在还在持续
另外目前 Weex 的团队构成并不只是前端,团队平时一起协作配合非常好,大家也普遍觉得比之前的 WeApp 更进一大步了,我把这些东西通过我们前端的博客发出来,也第一时间跟团队进行了交流。有同学也感叹说前端有一些天然的技术交流和分享的优势,其它技术圈似乎交流分享的少一些。大家甚至还在想要不要大家也都从各自的角度多写一点,尤其是 Weex/WeApp 的野史,找寒老师 @wintercn 几个人转转。所以我一开头提到的听到的声音应该是某些人的自己的猜测或错觉吧……
说到这里还是要再次感谢一下Vue,感谢一下 WeApp、Dynative、AliReactNative、鸟巢、WVC、PageKit、WindVane,Webkit,感谢一下团队的通力合作
大家不介意的话还是把关注的焦点回到技术方案本身吧:)
@andyforever 你提到的 options
字段可否有一些更形象的运用场景呢?我觉得这个字段和 data 蛮接近的
@stephenzhao 一方面是 @skyline0705 提到的方法,是用在 HTML5 环境下的,另一方面 Weex 自身会对样式先在组件内部做内联处理再发给 native 渲染,所以天然回避了这个问题。两者最终达到的目的和效果是一样的
option
这个字段看起来就像各种插件的参数,也就是为了达到组件复用
的目的吧。
这不是重复造轮子,很期待看 release 后的版本。
我更喜欢把weex叫成weed!!!!,觉得真心牛逼
@Jinjiang 场景如定义一个Grid组件,data用来存放columns、rows数据,options用来定义grid的各种属性,比如editable是否可编辑、rowHeight行高、enableColumnReorder是否可以点击列排序等; 定义一个tree组件,options这个对象属性可以有checkable是否可以复选、dblclickExpand双击展开等。
如@jincdream 所说,提高在不同场景下的复用性,跟data参数混合在一起就不免有些混乱了
像组件我们分出tpl、css、js三个外在属性文件一样,组件数据绑定也可以固定成options、data、methods(actions),这是组件的内在属性。
@andyforever 这个感觉和元素自定义的 attributes 蛮接近的,尤其是 virtual dom 抽象化之后
@andyforever 我是觉得
组件主要不是用来复用的,是用来分治的。
有完善的组件系统,应该也有完善的版本管理了,不同功能的需求应该在不同的版本之中去体现。不然组件就会变得越来越复杂。例如你现在的editable:true
,大概是可以编辑的意思吧,目前可能只有一个能不能编辑的分支,但后面的可能需求会增加,我这里可以编辑,但我这里编辑的时候可能要加上高亮,下划线,字体颜色改变什么的。。这时候,editable:false
的配置也就有了冗余的代码。所有我觉得这并不是值得发展的方向。
不过肯定有一些是可变动,而那些就像是react
的props
和state
,其实我们真正所需要的只是props
而且,options
应该要被放弃了。
@jincdream 不敢苟同。 对于不同的项目来说,最坏的结果是分治(不同项目能复用同一个组件当然是最好的)。对同一项目来说,分治是解决不了问题的。 像你说的props和state只是名字的区别,当然在模板上定义还是在数据绑定时定义,仁者见仁智者见智。
@Jinjiang 看了楼主的 Weex 的介绍了,和自己一直想要的开发方式几乎一模一样。现在最大的疑问是有两个,第一,编写的HTML(我暂时这么叫吧)在浏览器中是HTML的方式,那么在原生中,是不是转换成了原生的组件,如果是,这个组件和HTML的标签的对应关系你们怎么处理。第二,就是假设是把HTML转成了对应的原生组件。那么,如果别的公司要用自己的一套组件,比如我在H5中创建了一个 mg-slider 的组件,那么这个公司在原生层面,要做出对应的 Weex 的原生组件,需要怎么开发?
@andyforever @jincdream 二位的看法我中和一下,首先 props
和 state
可以分别理解为原始数据和最终展示相关的数据,类似 Vue 里的 data
和 computed
的感觉但不完全一样,因为在 Vue 里如果原始数据不需要加工就能直观的进行展示是不需要刻意转换成 computed
的。第二这些 config 我更倾向于用 webcomponents 的思路抽象成 custom attributes (也有个流行的叫法是 directive),这个我上一条也提到过,比如类似 <x editable>...</x>
、<input type="checkbox" checked value="...">
这种的——其实你会发现在 Weex 里我对 attr/props/data/config 等概念做了简化,都统一在了一起,即自定义元素外面写的 attr 就对应最里面的 data。我希望这里不要搞得太复杂太特殊,这会带来一些封装不完全和不严谨但是简单易用的优势也是很明显的,尤其今天的手机上复杂界面并不多,业务上更看重的是“动态性”方面的能力和灵活性。
@niluanxy 如果跟你想要的几乎一样那我们还觉得蛮有面子的:)
问题1:其实我们最主要的组件就是容器 (对应 HTML 里的 <div>
)、文字和图片,绝大部分内容都可以直接拿这三类组件 + Flexbox 布局搞定。我们主要就是原生实现了这三个核心的组件 + 引入 csslayout
问题2:如果创建了新的组件,则可以用 webcomponents 的方式规范好,然后扩展成“builtin component”集成到native里
@andyforever @Jinjiang
赞同勾股的,我希望这里不要搞得太复杂太特殊,这会带来一些封装不完全和不严谨但是简单易用的优势也是很明显的
,保持组件的易用性其实很重要。
刚刚想了下,可以复用的组件,其实是有的,这些应该往往是被依赖的核心组件了吧。
比如
其实我们最主要的组件就是容器 (对应 HTML 里的 < div >)、文字和图片
这里其实就是三个核心组件,而其他的组件都依赖于它们所形成的吧。
@andyforever 主要是 editable
这个词可以让联想到很多功能,如果只是单独的一个编辑快关,那它就像是一个可依赖的核心组件了,在不同项目上复用是没问题的。如果是为了能够让更多项目复用而写的一个组件,那这个组件应该是不健康的。我们大可以把这个开关editable
之前的功能抽离出来,再各个不同的项目上进行各自对editable
的封装。:)
因为移动设备的资源非常有限,所以就算同时打开多个 Weex 实例,也只能公用一个 JavaScript 实例,如何有效的让多个实例在 JavaScript 引擎中共存是个关键的问题
不知道我理解的问题对不对,和你们团队的同学沟通过,在引擎加载js的时候,强制把这个js包含在一个function里面,至少可以杜绝各个js之间的变量冲突。当然,你还需要屏蔽window等全局变量。
@dolmens 是的,原理是如此,但是怎么通过工具或实现从理论上杜绝问题还是要有些工程手段,最近有些眉目了,正在做尝试
没有看太明白,有个问题确认下,最终在native端执行的时候,是只有一个js引擎呢,还是也有xml和css的引擎?RN是只有js。
你们这么牛,马云知道吗?
其实大家都知道JS HTML CSS的这种前端开发模式在现在各种框架的支持下是最高效的,但是因为web页面在移动端的性能问题所以才搞这种写法是web的方式,但是运行是native的。不过我想知道为什么web也没这种dom树渲染的方式性能会差会卡呢?如果这个问题解决了是不是这些什么个xxx-native好像都没什么意义了呢?
66666!总之WEEX是吸收了RN和vue.js的一些设计思想并且更加适合手淘和猫客内的前端开发,集团内部赶紧推广起来:)
@Jinjiang 那明白了,其实就是相当于做了一个虚拟机一样,选择H5最主要的元素,以及兼容上Flex布局的语法,这样来达到对应到原生组件的效果,了然了,确实目前来说这种方式最实际,也最容易应用起来。
之前两篇我们分别谈到了对无线电商动态化的理解,以及我们自己的技术方案:Weex,今天我们分享一些其中的技术细节
data-binding
首先要介绍一下我们是怎么做到数据绑定的,首先,我们对上层撰写的代码遵循了传统的 mustache 书写习惯。即:
我们的 transformer 对这样的语法的解析思路非常简单直接,即:
{{xxx}}
),转换为:function () {return xxx}
所以上面的模板最终会被转换成:
在客户端的 JavaScript 引擎中,我们会进行这样的判断:
只要是函数类型,就进行数据绑定,否则一次性赋值,简单易懂易用。
这样在相应的数据发生改写的时候,界面结构和样式会通过
_bindKey
和updater
自动触发更新。关于如何在 JavaScript 上实现数据监听,也算是一个很重要的细节,不过市面上已经有大把优秀的实现案例了,我们也没有在这个环节上做特别的事情,所以不做赘述。(p.s. 在 Weex 的 JS Framework 中,我们复用了 Vue.js 的数据监听 (
observer/*.js
) 和依赖收集 (watcher.js
) 的代码实现,在此特别要感谢一下!)transformer
在 transformer 中,我们主要的工作就是对 HTML、CSS、JavaScript 代码进行解析和重组。这里我们用到了三个非常重要的库:
用 htmlparser 可以把 HTML 转换成 JSON
用 cssom 可以把 CSS 转换成对象供二次处理
用 uglify-js 可以把 JavaScript 代码进行细节解析处理
而且因为有了 transformer,我们可以把传统 mvvm 需要在客户端甚至 DOM 上完成的模板解析、数据绑定语法解析等工作提前处理完毕。所以免去了客户端运行时现解析模板源文件的负担。更酷的是,因为模板解析是不依赖真实 DOM 的,所以我们可以大大方方的把语法设计成
<img src="{{xxx}}">
而不必担心任何副作用。而高级的表达式、过滤器等数据绑定语法也都可以在 transformer 这一层提前处理好,这样在撰写体验持续增强的情况下,运行时并不会产生额外的负担——这都要归功于我们引入了这一层 transformerdebugger tools
我们为 native 界面调试设计了贴心的远程调试工具,主要解决三个痛点问题:
解决问题的办法是:
图:远程调试工具工作原理
这样,一个客户端开关,一个 websocket 服务器,一个本地的 JavaScript 引擎页面,一个开发者工具扩展,我们就实现了 Weex 的远程调试。
图:开发者工具的审查元素功能扩展
unit test 和 ci 实践
Weex 的 JavaScript 引擎作为一个相对底层的项目,品控需要做到非常严格和极致,否则一个小小的失误在客户端长期运行之后都有可能带来灾难性的后果。
本次 Weex 的开发当中,我们认真实践了基于 mocha、chai 和 sinon 的单元测试,每个源代码的文件夹都放了一个名叫
__test__
的文件夹,里面放了这个目录下所有同名的 JavaScript 文件,每个文件的内容都是当前文件夹内对应文件的测试用例。图:所有的源文件都在同级目录下有一个
__test__
文件夹放相应的测试代码在项目中后期,我们还引入了集团内部的一个 ci 系统,每次开发新功能,先开一个分支,然后写测试用例,最后进行代码实现知道跑通所有的 test case,搞定之后发起 merge request,ci 系统会自动在线上运行所有的回归测试,再次验证其正确性和各项指标。
图:项目分支管理
图:CI 实践
其实有关项目品控的话题还有很多,我们也在逐渐实践当中。
isomorphic (同构)
我们已经在内部版本实现了简单的服务端渲染,有了这个东西会怎样呢?
一旦我们可以在服务端直接渲染出界面的 JSON 结构,客户端就可以绕过 JavaScript 解析过程,直接根据 JSON 结构把界面渲染出来。与其对应的逻辑控制稍后也会初始化好,并和界面效果最终保持同步,但在整个过程中,首屏加载的时间会进一步缩短。而且,更令人兴奋的是,如果当前界面刚好没有交互逻辑,甚至后期的 JavaScript 也不需要参与了,这是一条更短的链路!
反哺 HTML5
通过对 Weex 技术方案的探索,我们把组件化开发、transformer 机制、同构等理念反哺到 HTML5 开发,会有什么样的惊喜呢?
那就是一个极简的针对无线前端的 HTML5 MVVM 库:我暂时取名叫做 v.js
v.js 的名字来自著名的 MVVM 库 Vue.js,我希望这个库更适合移动端,目前它可以具备所有 MVVM 的核心功能,通过 transformer 提前解析模板,运行时更快速,体积是 Vue.js 的 1/3,而且支持服务端的同构。这些都是基于移动端现状的二次改进,目前还在细节构思和研发当中。希望不久的将来可以跟大家见面。
基于 v.js 的源文件
v.js 的展示效果
同构的 JSON 数据,方便 native 快速渲染
同构的 HTML 代码,方便浏览器快速渲染
篇幅有限,写了三篇还是觉得不够,
期待和大家更多的交流。我晚上再针对大家频繁问及或感兴趣的问题做一个整理。欢迎继续阅读大家近期针对 Weex 的常见问题汇总整理阿里无线前端团队更多精彩的内容还在后面排队,我这边对无线电商动态化方案的思考就先写到这里了:)