weex学习与应用

2016年4月21日,阿里巴巴在Qcon大会上宣布开源跨平台移动开发工具Weex,Weex能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出Native级别的性能体验,并支持iOS、安卓、YunOS及Web等多端部署。
对于移动开发者来说,Weex主要解决了频繁发版和多端研发两大痛点,同时解决了前端语言性能差和显示效果受限的问题。开发者可通过Weex官网申请内测。(http://alibaba.github.io/weex/) 开发者只需要在自己的APP中嵌入Weex的SDK,就可以通过撰写HTML/CSS/JavaScript来开发Native级别的Weex界面。Weex界面的生成码其实就是一段很小的JS,可以像发布网页一样轻松部署在服务端,然后在APP中请求执行。

与 现有的开源跨平台移动开放项目如Facebook的React Native和微软的Cordova相比,Weex更加轻量,体积小巧。因为基于web conponent标准,使得开发更加简洁标准,方便上手。Native组件和API都可以横向扩展,方便根据业务灵活定制。Weex渲染层具备优异的性 能表现,能够跨平台实现一致的布局效果和实现。对于前端开发来说,Weex能够实现组件化开发、自动化数据绑定,并拥抱Web标准。

快速上手

参考文档:开发文档
Weex 是一套简单易用的跨平台开发方案,能以 web 的开发体验构建高性能、可扩展的 native 应用,为了做到这些,Weex 与 Vue 合作,使用 Vue 作为上层框架,并遵循 W3C 标准实现了统一的 JSEngine 和 DOM API,这样一来,你甚至可以使用其他框架驱动 Weex,打造三端一致的 native 应用。

Vue 是什么?

Vue.js 是 Evan You 开发的渐进式 JavaScript 框架。开发者能够通过撰写 *.vue 文件,基于 <template>, <style>, <script> 快速构建组件化的 web 应用。

Hello World

Playground App
尝试 Weex 最简单的方法是使用 Playground App 和在 dotWe 编写一个 Hello World 例子。你不需要考虑安装开发环境或编写 native 代码,只需要做下面两件事:
为你的手机安装 Playground App,当然,Weex 是跨平台的框架,你依然可以使用浏览器进行预览,只是这样你就无法感受到 native 优秀的体验了。
在新标签页中打开 Hello World 例子,点击预览,然后用 Playground 扫码即可。

<template>
  <div>
    <text class="text">{{text}}</text>
  </div>
</template>
<style>
  .text {
    font-size: 50;
  }
</style>
<script>
  export default {
    data () {
      return {
        text: 'Hello World.'
      }
    }
  }
</script>

搭建开发环境

第一步:安装依赖

brew install node
npm install -g weex-toolkit

国内开发者可以考虑使用淘宝的 npm 镜像 —— cnpm 安装 weex-toolkit

$ npm install -g cnpm --registry=https://registry.npm.taobao.org
$ cnpm install -g weex-toolkit

第二步:初始化

然后初始化 Weex 项目:

$ weex init awesome-project
执行完命令后,在 awesome-project 目录中就创建了一个使用 Weex 和 Vue 的模板项目。

第三步:开发

之后我们进入项目所在路径,weex-toolkit 已经为我们生成了标准项目结构。

在 package.json 中,已经配置好了几个常用的 npm script,分别是:

build: 源码打包,生成 JS Bundle
dev: webpack watch 模式,方便开发
serve: 开启静态服务器
debug: 调试模式
我们先通过 npm install 安装项目依赖。之后运行 npm run dev 和 npm run serve 开启watch 模式和静态服务器。

然后我们打开浏览器,进入 http://localhost:8080/index.html 即可看到 weex h5 页面。

初始化时已经为我们创建了基本的示例,我们可以在 src/foo.vue 中查看。

代码如下所示:

<template>
  <div class="wrapper">
    <text class="weex">Hello Weex !</text>
    <text class="vue">Hello Vue !</text>
  </div>
</template>
<style scoped>
  .wrapper {
    flex-direction: column;
    justify-content: center;
  }
  .weex {
   font-size: 60px;
   text-align: center;
   color: #1B90F7;
  }
  .vue {
   font-size: 60px;
   text-align: center;
   margin-top: 30px;
   color: #41B883;
  }
</style>

关于 Weex 语法部分,你可以直接参考 Vue Guide

集成到 iOS
通过cocoaPods 集成 Weex iOS SDK到你的项目
首先假设你已经完成了安装 iOS 开发环境CocoaPods
第一步:添加依赖
导入 Weex iOS SDK 到你已有的项目, 如果没有,可以参考新建项目在继续下面内容之前,确保你已有的项目目录有名称为 Podfile
文件,如果没有,创建一个,用文本编辑器打开
集成 framework
WeexSDK 在 cocoaPods 上最新版本 可以在获取
在 Podfile
文件中添加如下内容

source 'git@github.com:CocoaPods/Specs.git'
target 'YourTarget' do
platform :ios, '7.0'
pod 'WeexSDK', '0.9.5' ## 建议使用WeexSDK新版本
end

源码集成
首先 拷贝 ios/sdk
目录到你已有项目目录 (此处以拷贝到你已有项目的根目录为例子),然后在 Podfile
文件中添加

source 'git@github.com:CocoaPods/Specs.git'
target 'YourTarget' do
platform :ios, '7.0'
pod 'WeexSDK', :path=>'./sdk/'
end


第二步:安装依赖
打开命令行,切换到你已有项目 Podfile
这个文件存在的目录,执行 pod install
,没有出现任何错误表示已经完成环境配置。

第三步:初始化 Weex 环境
在 AppDelegate.m
文件中做初始化操作,一般会在 didFinishLaunchingWithOptions
方法中如下添加。

//business configuration
[WXAppConfiguration setAppGroup:@"AliApp"];
[WXAppConfiguration setAppName:@"WeexDemo"];
[WXAppConfiguration setAppVersion:@"1.0.0"];

//init sdk enviroment
[WXSDKEngine initSDKEnviroment];

//register custom module and component,optional
[WXSDKEngine registerComponent:@"MyView" withClass:[MyViewComponent class]];
[WXSDKEngine registerModule:@"event" withClass:[WXEventModule class]];

//register the implementation of protocol, optional
[WXSDKEngine registerHandler:[WXNavigationDefaultImpl new] withProtocol:@protocol(WXNavigationProtocol)];

//set the log level
[WXLog setLogLevel: WXLogLevelAll];


第四步:渲染 weex Instance
Weex 支持整体页面渲染和部分渲染两种模式,你需要做的事情是用指定的 URL 渲染 Weex 的 view,然后添加到它的父容器上,父容器一般都是 viewController。

#import <WeexSDK/WXSDKInstance.h>
- (void)viewDidLoad
{
[super viewDidLoad];

_instance = [[WXSDKInstance alloc] init];
_instance.viewController = self;
_instance.frame = self.view.frame;

__weak typeof(self) weakSelf = self;
_instance.onCreate = ^(UIView *view) {
[weakSelf.weexView removeFromSuperview];
[weakSelf.view addSubview:weakSelf.weexView];
};

_instance.onFailed = ^(NSError *error) {
//process failure
};

_instance.renderFinish = ^ (UIView *view) {
//process renderFinish
};
NSURL *url = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"js"]
[_instance renderWithURL:url options:@{@"bundleUrl":[self.url absoluteString]} data:nil];
}

WXSDKInstance 是很重要的一个类,提供了基础的方法和一些回调,如 renderWithURL
, onCreate
, onFailed
等,可以参见 WXSDKInstance.h
的声明。
第五步:销毁 Weex Instance
在 viewController 的 dealloc 阶段 销毁掉 Weex instance,释放内存,避免造成内存泄露。

- (void)dealloc
{
[_instance destroyInstance];
}

导入 Weex SDK framework 到工程
可以通过源码编译出 Weex SDK,可以在新的 feature 或者 bugfix 分支,尝试最新的 feature。
参考此处直接导入 weexSDK。

工作原理

整体架构
Weex 表面上是一个客户端技术,但实际上它串联起了从本地开发环境到云端部署和分发的整个链路。开发者首先可以在本地像撰写 web 页面一样撰写一个 app 的页面,然后编译成一段 JavaScript 代码,形成 Weex 的一个 JS bundle;在云端,开发者可以把生成的 JS bundle 部署上去,然后通过网络请求或预下发的方式传递到用户的移动应用客户端;在移动应用客户端里,WeexSDK 会准备好一个 JavaScript 引擎,并且在用户打开一个 Weex 页面时执行相应的 JS bundle,并在执行过程中产生各种命令发送到 native 端进行的界面渲染或数据存储、网络通信、调用设备功能、用户交互响应等移动应用的场景实践;同时,如果用户没有安装移动应用,他仍然可以在浏览器里打开一个相同的 web 页面,这个页面是使用相同的页面源代码,通过浏览器里的 JavaScript 引擎运行起来的。

How it works
How it works

本地开发环境
Weex 的本地开发环境基于 web 开发体验而设计,web 开发者可以通过自己熟悉的 HTML/CSS/JavaScript 技术和语法实现移动应用的界面。同时 Weex 也对 Vue.js 这一非常优秀的前端框架做了官方的支持。
除此之外,Weex 的工程设计也是 web 开发者非常熟悉的,首先 web 开发者可以使用自己熟悉的 npm 进行依赖管理;其次 web 开发者在通过项目脚手架初始化工程、开发、调试、质量控制等各个环节,都可以参考 web 开发已有的最佳实践。
和如今 web 开发的最佳实践一样,Weex 会把一个页面的源代码全部编译打包成一个 JS bundle,在浏览器中,我们需要把这个 JS bundle 作为一段 <script>
载入网页,在客户端里,我们把这段 JS bundle 载入本地,并通过 WeexSDK 直接执行。

云端部署和分发
Weex 的 JS bundle 可以作为 web 开发中的一段静态资源进行部署和下发。几乎可以复用 HTML5 所有的工程体系和最佳实践。比如在本地开发环境通过部署工具将 JS bundle 部署到 CDN、通过 CMS 或搭建平台把业务数据和模块化的前端组件自动化拼接生成 JS bundle、通过服务端 JS bundle 的流量和日志统计页面的访问情况、通过 AppCache 或类似的方式对 JS bundle 在客户端进行缓存或预加载以降低网络通信的成本等。

客户端 JavaScript 引擎
Weex 的 iOS 和 Android 客户端中都会运行一个 JavaScript 引擎,来执行 JS bundle,同时向各端的渲染层发送规范化的指令,调度客户端的渲染和其它各种能力。我们在 iOS 下选择了 JavaScriptCore 内核,而在 Android 下选择了 UC 提供的 v8 内核。无论是从性能还是稳定性方面都提供了强有力的保障。
为了让整个移动应用的资源利用得更好,我们在客户端提供的 JavaScript 引擎是单例的,即所有 JS bundle 公用一个 JavaScript 内核实例,同时对每个 JS bundle 在运行时进行了上下文的隔离,使得每个 JS bundle 都能够高效安全的工作。我们还把 Vue 2.0 这样的 JS Framework 做了预置,开发者不必把 JS Framework 打包在每个 JS bundle 里,从而大大减少了 JS bundle 的体积,也就进一步保障了页面打开的速度。

客户端渲染层
Weex 目前提供了 iOS 和 Android 两个客户端的 native 渲染层。每个端都基于 DOM 模型设计并实现了标准的界面渲染接口供 JavaScript 引擎调用。并且结合 web 标准和 native 的特点和优势实现了一套统一的组件和模块。Weex 在性能方面的表现也是非常优异的,尤其是界面首屏加载时间、native 下长列表的资源开销和复用情况、CPU、内存、帧率 等关键指标。当然,尽管 Weex 官方已经提供了一组开发者最常用的组件和模块,但面对丰富多样的移动应用研发需求,团队也难免会力不从心,为此我们提供了灵活自由的横向扩展能力,开发者可以根据自身的情况定制属于自己的客户端组件和模块,进一步丰富 Weex 在客户端上的能力。


浏览器渲染
Weex 除了提供 iOS 和 Android 的客户端渲染层之外,还基于 Vue 2.0 对官方的所有组件和模块进行了封装,开发者可以基于 Vue 2.0 用同一套源代码构建出在浏览器中相同效果的页面。并且同样可以横向扩展。

一次撰写,多端运行

Weex 提供了多端一致的技术方案。

首先 web 开发体验在各端当中是相同的。包括语法设计和工程链路。
其次,Weex 的组件、模块设计都是 iOS、Android、Web 的开发者共同讨论出来的,有一定的通用性和普遍性。
Weex 开发同一份代码,可以在不同的端上分别执行,避免了多端的重复研发成本。

Weex 页面结构

一个 Weex 页面就是一个相对独立解耦的移动应用界面,它不仅包括了界面展示、更包含了逻辑处理、设备能力使用、生命周期管理等部分。
界面
DOM 模型
Weex 页面通过类似 HTML DOM 的方式管理界面,首先页面会被分解为一个 DOM 树,,每个 DOM 结点都代表了一个相对独立的 native 视图的单元。然后不同的视图单元之间通过树形结构组合在了一起,构成一个完整的页面。
相关链接
Weex Native DOM APIs

组件
Weex 支持文字、图片、视频等内容型组件,也支持 div、list、scroller 等容器型组件,还包括 slider、input、textarea、switch 等多种特殊的组件。Weex 的界面就是由这些组件以 DOM 树的方式构建出来的。
相关链接
Weex 组件列表

布局系统
Weex 页面中的组件会按照一定的布局规范来进行排布,我们这里提供了 CSS 中的盒模型、flexbox 和 绝对/相对/固定/吸附布局这三大块布局模型。
盒模型:通过宽、高、边框、内外边距、边框等 CSS 属性描述一个组件本身的尺寸。
flexbox:通过 CSS 3 Flexbox 布局规范定义和描述组件之间的空间分布情况。
position:支持 CSS position 属性中的 absolute
, relative
, fixed
, sticky
位置类型,其中 relative
是默认值。

功能
Weex 提供了非常丰富的系统功能 API,包括弹出存储、网络、导航、弹对话框和 toast 等,开发者可以在 Weex 页面通过获取一个 native module 的方式引入并调用这些客户端功能 API。

生命周期
每个 Weex 页面都有其自身的生命周期,页面从开始被创建到最后被销毁,会经历到整个过程。这是通过对 Weex 页面的创建和销毁,在路由中通过 SDK 自行定义并实现的。

使用 weex-toolkit

weex-toolkit 是官方提供的一个脚手架命令行工具,你可以使用它进行 Weex 项目的创建,调试以及打包等功能。
安装

weex-toolkit
支持预览你当前开发的weex页面(.we
或者.vue
),你只需要指定预览的文件路径即可:

$ weex src/foo.vue

浏览器会自动弹出页面,这个时候你可以看到你所编辑的 Weex页面的具体效果和页面布局。如果你使用 Playground 扫描右边的二维码,就能够看到 Weex 在 Android/IOS 设备上的效果了。
如果你需要预览整个项目目录,你可以输入这样的命令:

$ weex src --entry src/foo.vue

你需要在传入的参数指定预览的目录和入口文件。
打包weex项目
如果开发完成后,你可以使用 weex compile
通过命令行工具进行单个文件或者整个项目的打包。

weex compile src/foo.vue dist

命令行需要两个参数,你的源码文件或者目录, 以及你生成打包后的目录地址。
调试 Weex 页面
weex-toolkit支持调试工具。weex devtools ,它是专门为Weex定制的一款实现了 Chrome Debugging Protocol 的 inspect/debug 工具,能够帮助你快速查看 app 运行状态和调试 Weex 中的 JS 代码,当前支持 IOSAndroid 两个平台。
用法

weex debug [options] [we_file|bundles_dir]

选项:

-h, --help 显示帮助
-V, --verbose 显示 debug 服务器运行时的各种 log
-v, --version 显示版本
-p, --port [port] 设置 debug 服务器端口号 默认为8088
-e, --entry [entry] debug 一个目录时,这个参数指定整个目录的入口 bundle 文件,这个 bundle 文件的地址会显示在 debug 主页上(作为二维码)
-m, --mode [mode] 设置构建 we 文件的方式,transformer 最基础的风格适合单文件, loader:webpack 风格 适合模块化的多文件 . 默认为 transformer

开启调试

$ weex debug

单纯启动一个调试服务器,并同时唤起Chrome浏览器打开调试主页
。这个调试主页
上会有一个二维码,使用 Playground App 扫这个二维码可以开启 Playground 调试。开启调试后,设备列表中会出现您的设备,根据提示进行后续的调试操作。
调试 .we
| .vue
文件

$ weex debug your_weex.vue

这个命令会将 your_weex.vue
编译成 JS Bundle
文件 部署到 debug 服务器;并启动debug服务器如上述命令那样打开的调试vue主页
会多显示一个二维码,使用 Playground App扫这个二维码码可以加载 your_weex.we
(注意要先扫描开启调试的那个二维码码)。这个命令会自动检测 your_weex.we
文件变动,如果发现内容被修改则立即重新编译部署,并刷新 debugger
页面。.
调试整个bundle/we文件夹
同样你也可以调试整个目录的文件,你只需要传入目录的路径和入口文件即可;

$weex debug your/we/path -e index.we

这个命令会编译你指定目录下的所有的 .we
文件,并把编译好的 JS Bundle 部署到 debug 服务器,他们的地址会映射到 http://lcoalhost:8088/weex/ 下比如 your/we/path/index.we
可以通过 http://lcoalhost:8088/weex/index.js 访问。your/we/path/demo/test.we
可以通过 http://lcoalhost:8088/weex/demo/index.js
-e
参数可以指定一个入口的 .we
文件,这个文件的地址会显示在调试主页
上(作为二维码)。

Weex 和 React Native的比较

Weex和React Native的异同

相同点:

都采用Web的开发模式,使用JS开发;
都可以直接在Chrome中调试JS代码;
都支持跨平台的开发;
都可以实现hot reload,边更新代码边查看效果;

不同点:
JS引擎
什么是JS引擎
学习成本
1.环境配置:ReactNative需要按照文档安装配置很多依赖的工具,相对比较麻烦。 weex安装cli之后就可以使用

2.vue vs react:上面已经做过对比react模板JSX学习使用有一定的成本 vue更接近常用的web开发方式,模板就是普通的html,数据绑定使用mustache风格,样式直接使用css

社区支持
Weex开源较晚,互联网上相关资料还比较少,社区规模较小;
React Native社区则比较活跃,可以参考的项目和资料也比较丰富
一张图:从渲染时间,内存使用,CPU占用,帧率(图形处理器每秒钟能够刷新几次,高的帧率可以得到更流畅、更逼真的动画。每秒钟帧数 (fps) 愈多,所显示的动作就会愈流畅。)

1494773-b0456449011ffa04.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容