重磅!!!Chameleon支持快应用————快应用官方&&滴滴合作研发出品
背景
计算机技术历史发展告诉我们,每一种新技术出现都会经历 "各自为政" 的阶段,小程序技术也不例外。微信小程序作为首创者,虽然其他小程序都在技术实现原理、接口设计刻意模仿,但是作为一线开发者面对同样的应用实现往往需要重复开发、测试,从前 1 单位的工作量变成了 N 单位的工作量。
除此之外,自跨平台兴起以来,各种各样的框架层出不穷,从一开始的 Hybrid App ( PhoneGap / Cordova / Ionic ),到前两年热门的 React-Native 和 Weex,再到目前风头正盛的 Flutter,这期间还兴起了 Web App 的热潮 (PWA 和各种小程序),这还不包括 watch、TV、车载 APP 等其他 “端”。
Chameleon(简写 CML )是一款真正专注于让一套代码运行多端的跨端框架。Chameleon 团队秉承 "一套代码运行多端,一端所见即多端所见" 的初心,拥有业内先进的工程化设计、丰富的基础以及独创多态协议,提供标准的 MVVM 架构开发模式统一各类终端。在最初支持 web、weex、wx【微信小程序】三端之后,凭借其多态协议的优秀设计思想、灵活的工程化配置以及跨端标准协议,CML 工具可以迅速扩展新端,目前已经成功扩展支持全平台小程序(微信、支付宝、百度、qq、头条)。快应用也沿用着 MVVM 的架构开发模式,因此,基于CML的跨端标准协议扩展快应用后,可以快速实现一套代码运行web、native、全平台小程序、快应用。
image选型和思考
当前阶段在开源社区存在多种跨端解决方案,除了滴滴的 Chameleon 跨端框架,诸如京东的 Taro 、去哪网的 Nanachi 、美团的 mpvue、腾讯的 WePY、Dcloud 的 uni-app 等跨端框架也都有各自的生态和使用场景。在选型方面,我们对这些框架的生态进行了较为细致的比较和探究,对比结果如下:
框架 | Chameleon | mpvue | Taro | Uni-app | Wepy |
---|---|---|---|---|---|
DSL | CML/类Vue | Vue | JSX | Vue | 类Vue |
语法校验工具 | 自研工具 | 无 | ESlint规则 | IDE支持 | 无 |
Typing/自动补全 | 有 | 有 | 有 | 有 | 有 |
样式 | sass,less,stylus | sass,less,stylus | sass,less,stylus | sass,less,stylus | sass,less,stylus |
多端支持 | Web、weex、微信、支付宝、百度、qq、头条、快应用 | 微信 | Web、RN、微信、支付宝、百度、头条、qq、快应用 | web、Android、IOS、微信、支付宝、百度、头条、qq | 微信 |
移动端容器 | weex | 无 | RN | Weex | 无 |
移动端增强 | ChameleonSDK | 无 | 无 | nvue | 无 |
多端编译方式 | 自研多态协议+同时支持条件编译 | 环境变量条件编译 | 环境变量条件编译 | 环境变量条件编译 | 环境变量条件编译 |
H5兼容API | 自研多态协议 | 无 | 有 | 有 | 无 |
跨端组件库 | 有 | 无 | 有 | 有 | 无 |
第三方组件库 | 丰富 | 丰富 | 丰富 | 丰富 | 丰富 |
demo | 丰富 | 丰富 | 丰富 | 丰富 | 丰富 |
状态管理工具 | Chameleon-store | Vuex | Redux/Mobx/Dva | Vuex | Vuex |
统一性 | 路由、项目、页面、组件、API、尺寸单位等各端使用一致 | 仅支持微信小程序,不存在统一性 | react框架、微信小程序组件、微信小程序API,告知用户差异,用户按端兼容性调用 | 路由、项目、页面、组件、API、尺寸单位等各端使用一致 | 仅支持微信小程序,不存在统一性 |
差异化 | 多态协议隔离差异化 | 仅支持微信小程序,不存在差异化 | 环境变量判断混合差异化 | 环境变量判断混合差异化 | 仅支持微信小程序,不存在差异化 |
工程化扩展 | 本地调试服务、多类数据Mock线上代理调试 | 本地调试服务 | 无 | 本地调试服务 | 本地调试服务 |
组件导出 | 有 | 无 | 无 | 无 | 无 |
语法检查 | chameleon-linter全面检查 | 无 | 无 | 无 | 无 |
各端组件导入强规范 | 有 | 无 | 无 | 无 | 无 |
框架设计点 | 一套代码运行多端 | 小程序语法增强:用vue写小程序 | 推广某个框架写小程序:用React写小程序 | 一套代码运行多端 | 小程序语法增强:让小程序支持组件化开发的框架 |
除了以上对比之外
-
chameleon-tool 最新版本对分包进行了更大的细化,主包体积有效的较之前减少了40% 左右;具体参考 chameleon-分包
-
得益于chameleon的灵活的工程化配置,chameleon可以灵活的支持微信小程序的云开发,具体参考chameleon支持云开发
设计思想方面,Chameleon 独树一帜,独创跨端标准协议、灵活的工程化配置、Chameleon-store 状态管理工具,以及丰富的多端支持 【支持 Weex、快应用、Web 】,此外,Chameleon 不仅仅是作为跨端解决方案,让开发者高效、低成本开发多端原生应用,而且还基于优秀的前端打包工具 Webpack,吸收了业内多年来积累的最有用的工程化设计,提供了前端基础开发脚手架命令工具,帮助端开发者从开发、联调、测试、上线等全流程高效的完成业务开发。正是基于以上种种优势,快应用团队选择和 Chameleon 团队进行合作,作为快应用官方开展从 Chameleon 到快应用的适配工作。作为快应用官方团队,我们对快应用本身的能力和限制更加熟悉和了解,对 Chameleon 转换快应用的细节点能实现地更高效和完美,对于当前暂时未实现的特性也会第一时间进行跟进并持续更新给开发者,力图第一时间完善和优化。
快应用介绍
快应用简介
- 快应用是基于手机硬件平台的新型应用形态,覆盖 10 亿安卓设备;
- 快应用标准是由主流手机厂商组成的快应用联盟联合制定;
- 快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放;
- 快应用具备传统 APP 完整的应用体验,无需安装、即点即用;
快应用技术方案
快应用目前使用如下技术方案:
- 使⽤前端技术栈(Html / CSS / JavaScript);
- 使⽤前端主流的模版+数据绑定框架编写代码(Vue.js);
- 平台提供⼤量扩展能⼒,包括系统能⼒和服务集成能⼒;
- 默认使⽤原⽣ JS-Native 渲染,达到原⽣应⽤的性能和体验;
<template>
<!-- template里只能有一个根节点 -->
<div class="container">
<text class="title">测一测{{ title }}</text>
</div>
</template>
<style>
.container {
flex-direction: column;
justify-content: center;
}
.title {
font-size: 40px;
text-align: center;
}
</style>
<script>
export default {
data: {
title: '快应用'
}
}
</script>
快应用平台服务架构
<table style="margin-left: auto; margin-right: auto;">
<tr>
<td>
<img src="https://raw.githubusercontent.com/quickappcn/cml-extplatform-quickapp/master/platform.jpg" />
</td>
<td>
<div>Platform Service:</div>
<div>平台服务,提供如何存储,场景接口,分发下载,数据统计</div>
————————————
<div>Developer Service:</div>
<div>开发者服务,提供开发者文档及相关工具(IDE,Sign等)</div>
————————————
<div>Application Platform:</div>
<div>小程序运行平台,包含运行时,沙箱运行环境,小程序管理等</div>
————————————
<div>EntranceApp:</div>
<div>接入小程序平台sdk的应用,如商店等</div>
————————————
<div>Application:</div>
<div>具体小程序</div>
</td>
</tr>
</table>
快应用技术架构
<table style="margin-left: auto; margin-right: auto;">
<tr>
<td>
<img src="https://raw.githubusercontent.com/quickappcn/cml-extplatform-quickapp/master/framework.jpg" />
</td>
<td>
<div>App:</div>
<div>具体小程序,采用vue.js框架语法</div>
————————————
<div>JS Framework:</div>
<div>JS框架</div>
————————————
<div>JS Engine:</div>
<div>JS引擎,目前采用Google V8</div>
————————————
<div>JS-Native Bridge:</div>
<div>JS Native通信,目前采用开源J2V8方案</div>
</td>
</tr>
</table>
对比小程序
目前小程序普遍采用 Webview 方案进行渲染,快应用则基于原生 JS-Native 进行渲染,两者对比如下:
方案/对比 | 实现方案 | 性能 | 安全性 | 体验 | 接入成本 | 兼容性 |
---|---|---|---|---|---|---|
WebView 方案 | 基于 WebView Core 渲染和运行,部分组件使用 Native 原生实现 | 受限于 WebView 内核实现,且不同内核实现不一致,稳定性风险大 | 采用反射调用系统接口,不可控 | 在交互动效、加载效率层面无法达到 Native App 的效果 | 1.已有 Web 实现,少量修改即可接入;�2.没有 Web 实现,需要重新开发,成本较低; | 不同系统版本 WebView 无法保证一致性,内核碎片化严重,需要独立维护 WebView |
JS-Native 渲染 | 基于 JS 引擎解析,Native 环境渲染 | 本地渲染和解析,实现方案统一,效率高,风险可控,稳定性较好 | 客户端前端通过协议实现接口,安全性高 | 等同 Native App 的体验 | 需要按照协议重新实现,但前端开发,成本也较低 | 通信协议、JS 引擎、Native 环境全部一致,不存在兼容性问题 |
新端扩展快应用 ———— 原理篇
参与方
-
快应用团队
-
滴滴团队
-
开源贡献者
新端扩展配置化实现
chameleon-tool 中对于外部扩展的 webpack 配置的源码,参考:(https://github.com/didi/chameleon/blob/0.3.x-alpah-merge-mvvm/packages/chameleon-tool/configs/mvvm/getExtendConfig.js)
这里重点讲下处理 .cml 后缀文件的 mvvm-cml-loader 和 mvvm-pack 中的 MvvmGraphPlugin
配置如下
entry: {
app: path.join(cml.projectRoot, 'src/app/app.cml')
},
module: {
rules: [
...utils.styleLoaders({
type
}),
{
test: /\.cml$/,
use: [{
loader: 'mvvm-cml-loader',
options: {
loaders: getCmlLoaders(),
cmlType: type,
media,
check: cml.config.get().check
}
}]
}
]
},
plugins: [
new MvvmGraphPlugin({
cmlType: type,
media
}, platformPlugin)
]
mvvm-cml-loader 源码参考以下链接:(https://github.com/didi/chameleon/blob/0.3.x-alpah-merge-mvvm/packages/mvvm-cml-loader/index.js)
主要作用是以 app.cml 为入口,通过内联 loader 的形式循环递归的添加依赖,将所有的依赖添加到 webpack 构建过程中。
mvvm-pack 源码参考此处:(https://github.com/didi/chameleon/tree/0.3.x-alpah-merge-mvvm/packages/mvvm-pack)
mvvmGraphPlugin.js 中劫持了 webpack 的输出,通过 mvvmCompiler 生成构建图。
compiler.plugin('should-emit', function(compilation) {
try {
mvvmCompiler.run(compilation.modules);
} catch (e) {
cml.log.error(e);
}
// 返回false 不进入emit阶段
return false;
})
[图片上传失败...(image-ae3c1d-1581604675378)]
以上就是 CML 脚手架产生的树状结构图,递归传递给 cml-quickapp-plugin 来转义目标语法。
实现cml-quickapp-plugin
目标:将包含 template、script、style 等节点的 .cml 源文件编译转换成符合快应用语法的 .ux 文件
根据上面生成的构建图,编译插件 cml-quickapp-plugin 中可以对构建图中所有节点(包括 template 节点、 style节点、script 节点 、json 节点等)编译成符合快应用端的语法,然后在 pack 任务中打包输出成符合快应用端的结构。
module.exports = class DemoPlugin {
constructor(options) {
......
}
/**
* @description 注册插件
* @param {compiler} 编译对象
* */
register(compiler) {
// 编译script节点,比如做模块化
compiler.hook('compile-script', function (currentNode, parentNodeType) {})
// 编译template节点 语法转义
compiler.hook('compile-template', function (currentNode, parentNodeType) {})
// 编译style节点 比如尺寸单位转义
compiler.hook('compile-style', function (currentNode, parentNodeType) {})
// 编译结束进入打包阶段
compiler.hook('pack', function (projectGraph) {
// 遍历编译图的节点,进行各项目的拼接
// 调用writeFile方法写入文件
// compiler.writeFile()
})
......
}
}
以扩展快应用的 template 编译为例。判断原始 CML 文件中的依赖关系,改写成快应用 <import ... ></import>
的写法
compiler.hook("compile-template", function (currentNode, parentNodeType) {
let {componentFiles, uximports} = currentNode.parent.extra || {};
currentNode.output = templateParser(currentNode.source);
let components = '';
if(componentFiles) {
Object.keys(componentFiles).forEach(key=>{
let targetEntry = cmlUtils.getPureEntryName(componentFiles[key], self.cmlType, cml.projectRoot);
let sourceEntry = cmlUtils.getPureEntryName(currentNode.realPath, self.cmlType, cml.projectRoot);
let relativePath = cmlUtils.handleRelativePath(sourceEntry, targetEntry);
components += `<import name='${key}' src='${relativePath}'></import>\n`
})
// 记录引入的组件
currentNode.importComponents = components;
} else if(uximports) {
uximports.forEach(item=>{
components += `<import name='${item.name}' src='${item.src}'></import>\n`
})
// 记录引入的组件
currentNode.importComponents = components;
}
});
更为详细的开发编译插件的教程请参考这个链接:https://cml.js.org/doc/extend/start.html
实现cml-quickapp-runtime
目标:实现运行时,代理快应用的 createApplication、createPage、createComponent 方法和响应式系统的 data、props、computed 等系统属性以及完成 CML 到快应用的生命周期映射
运行时的主要作用是抹平各端的生命周期差异性,进行响应式数据绑定等,参考这个链接https://cml.js.org/doc/extend/runtime.html
CML 和快应用的生命周期都包含 App、Page、Component 三个级别,映射关系如下。具体可以参考 https://github.com/quickappcn/cml-extplatform-quickapp/blob/master/packages/cml-quickapp-runtime/src/util/util/lifecycle.js
// 左侧的 key 为 CML 生命周期函数,右侧的 value 为快应用对应的生命周期函数
{
app: {
beforeCreate: "onCreate",
created: "onCreate",
beforeMount: "onCreate",
mounted: "onCreate",
beforeDestroy: "onCreate",
destroyed: "onDestroy"
},
page: {
beforeCreate: "onInit",
created: "onInit",
beforeMount: "onInit",
mounted: "onReady",
beforeDestroy: "onHide",
destroyed: "onDestroy",
onShow: "onShow",
onHide: "onHide"
},
component: {
beforeCreate: "onCreate",
created: "onCreate",
beforeMount: "onCreate",
mounted: "onReady",
beforeDestroy: "onInit",
destroyed: "onDestroy"
}
}
以上两行代码是在 mvvm-cml-loader 中插入的,具体实现参考源码中对于 script 节点的处理;
(https://github.com/didi/chameleon/blob/0.3.x-alpah-merge-mvvm/packages/mvvm-cml-loader/selector.js)
我们只需要实现对应端的以下几个方法:
createApp createPage createComponent
具体实现参考:
以 cml-quickapp-runtime 中的 createPage 实现为例:
(https://github.com/quickappcn/cml-extplatform-quickapp/tree/master/packages/cml-quickapp-runtime)
cml-quickapp-runtime/index.js
import { createApp } from './src/interfaces/createApp/index.js';
import { createPage } from './src/interfaces/createPage/index.js';
import { createComponent } from './src/interfaces/createComponent/index.js';
export default {
createApp,
createPage,
createComponent
}
cml-quickapp-runtime/src/interfaces/createPage/index.js
import createPgInterface from './index.interface';
export function createPage(options) {
return createPgInterface.createPage(options)
}
cml-quickapp-runtime/src/interfaces/createPage/index.interface
//这里要将 chameleon-runtime中的 createPage接口 include 进来
<include src="chameleon-runtime/src/interfaces/createPage/index.interface"></include>
<script cml-type="cml-quickapp">
import {Page} from '../../cml-quickapp'
class Method implements createPageInterface {
createPage(options) {
return new Page(options);
}
}
export default new Method();
</script>
实现cml-quickapp-api
目标:基于跨端协议,实现快应用对应的 API
实现 API 的部分特别简单,只需两步
-
引入 Chameleon 官方的标准 interface 文件
-
扩展实现新端,实现对应端的方法
具体实现如下:
以快应用的 alert 接口实现为例,参考 https://github.com/quickappcn/cml-extplatform-quickapp/blob/master/packages/cml-quickapp-api/src/interfaces/alert/index.interface
// 引入官方标准interface文件
<include src="chameleon-api/src/interfaces/alert/index.interface"></include>
// 扩展实现新端
<script cml-type="quickapp">
class Method implements uiInterface {
alert(opt, successCallBack, failCallBack) {
const { message, confirmTitle} = opt;
// quickapp 变量已经提前在 cml-quickapp-plugin 阶段即编译转化阶段注入,
// 参考 https://github.com/quickappcn/cml-extplatform-quickapp/blob/master/packages/cml-quickapp-plugin/index.js
quickapp.prompt.showDialog({
title: '',
message,
buttons: [
{
text: confirmTitle
}
],
success: () => successCallBack(confirmTitle),
cancel: () => failCallBack(confirmTitle),
fail: () => failCallBack(confirmTitle)
})
}
}
export default new Method();
</script>
实现cml-quickapp-store
目标:基于 mobx 实现一套响应式数据系统
实现 cml-quickapp-store 同样只需要两步:
-
引入 Chameleon 官方的标准 interface 文件
-
扩展实现新端,实现对应端的方法
//引入官方标准 interface 文件
<include src="chameleon-store/src/interfaces/createStore/index.interface"></include>
<script cml-type="quickapp">
import createStore from '../../platform/quickapp'
class Method implements createStoreInterface {
createStore(options) {
return createStore(options)
}
}
export default new Method();
</script>
实现 cml-quickapp-ui-builtin
目标:实现 CML 组件在快应用中的一致表现,可以参考 https://cml.js.org/doc/extend/ui-builtin.html
实现 cml-quickapp-ui-builtin 也是需要两步:
-
创建和 Chameleon 官方的组件同名的 interface 文件
-
用新端自有的组件和语法呈现 CML 组件即可。
以 CML 中的 button 组件实现为例,在快应用目前版本是不存在 button 组件的,所以需要用快应用自有的组件进行模拟实现,参考 https://github.com/quickappcn/cml-extplatform-quickapp/blob/master/packages/cml-quickapp-ui-builtin/components/button/button.quickapp.cml
// button.interface
<include src="chameleon-ui-builtin/components/button/button.interface"></include>
<script cml-type="quickapp" src="./button.quickapp.cml"></script>
// button.quickapp.cml
// template 实现 button 组件的 dom 结构,script 实现 button 的逻辑,style 实现 button 的样式效果
<template>
<div class="{{btnClasses}}" style="{{mrBtnStyle}}" onclick="clickHandler" ontouchstart="touchstart"
ontouchend="touchend">
<text c-if="{{text}}" class="{{textClasses}}" style="{{mrTextStyle}}">{{text}}</text>
<block c-else></block>
</div>
</template>
<script>...</script>
<style>...</style>
实现cml-quickapp-ui-builtin和实现cml-quickapp-ui
目标:扩展新端本身没有的复合交互组件,如 pop-up、action-sheet、picker 等交互组件。
实现过程和 cml-quickapp-ui-builtin 如出一辙,以 c-popup 组件的实现为例,参考 https://github.com/quickappcn/cml-extplatform-quickapp/blob/master/packages/cml-quickapp-ui/components/c-popup/c-popup.cml
// c-popup.interface
<include src="cml-ui/components/c-popup/c-popup.interface"></include>
// c-popup.cml
<template>
<view>
<view c-if="{{show}}" class="c-popup" style="{{containerStyle}}">
<view class="{{maskClass}}" c-bind:tap="closeevent"></view>
<!-- c-catch禁止事件冒泡 -->
<view class="c-popup-content" style="{{contentStyle}}" c-catch:tap="contentTap">
<slot></slot>
</view>
</view>
</view>
</template>
<script>...</script>
<style>...</style>
接入和使用
体验快应用
Chameleon 官方的体验 demo 项目源仓库如下:
- **cml-demo **: 组件库&&API 实例
- cml-flexbox : Flex 布局案例集合
- cml-yanxuan : 仿网易严选 APP
- cml-todomvc : Todo-List
以上四个项目编译打包后的快应用 .rpk 文件地址如下:
对于普通用户或开发者来说,如果想要在快应用端进行体验,需要满足以下条件:
- 拥有一台 Android 操作系统的移动设备
- 在移动设备上下载并安装最新版 快应用预览版 APP ,当前最新版本为1050.10
- 将以上 demo 项目编译打包生成的 .rpk 文件放入移动设备的 /sdcard/rpks 文件夹,再次打开预览版即可体验
<div style="display: flex;flex-direction: row;justify-content: space-around">
<img src="https://raw.githubusercontent.com/quickappcn/cml-extplatform-quickapp/master/rpks.jpg" height="600px" />
<img src="https://raw.githubusercontent.com/quickappcn/cml-extplatform-quickapp/master/preview.jpg" height="600px" />
</div>
在快应用端的预览效果如下:
<div style="display: flex">
<img src="https://raw.githubusercontent.com/quickappcn/cml-extplatform-quickapp/master/base.png" width="200px" height="400px"/>
<img src="https://raw.githubusercontent.com/quickappcn/cml-extplatform-quickapp/master/flexbox.png" width="200px" height="400px"/>
<img src="https://raw.githubusercontent.com/quickappcn/cml-extplatform-quickapp/master/yanxuan.png" width="200px" height="400px" />
<img src="https://raw.githubusercontent.com/quickappcn/cml-extplatform-quickapp/master/todo.png" width="200px" height="400px"/>
</div>
接入快应用
首先要求具备一整套快应用开发工具链,参考链接:https://www.quickapp.cn/docCenter/post/69,这其中包括快应用调试器、快应用预览版、hap-toolkit 构建工具等;运行 快应用示例代码 可以检验环境是否就绪;快应用的开发环境就绪之后才开始进行 chameleon 项目的引入和部署。
基于以下步骤配置之后,既有的 CML 项目可以直接在快应用运行
全局安装最新的 chameleon-tool 工具
npm i -g chameleon-tool
启动快应用服务
此处以及下文均以 quickapp-demo
为例命名该快应用项目,并以 ~/quickapp-demo 目录为例启动快应用服务,此外,建议开发者在快应用项目根目录 ~/quickapp-demo/
执行 hap watch
,进行代码热更新。
cd ~/quickapp-demo
hap server # 启动快应用服务
# 再新打开另外一个terminal
cd ~/quickapp-demo
hap watch # 热更新
安装和更新package
克隆 chameleon 官方的 demo 项目到本地,此处以 cml-flexbox 项目为例。切换到 master-quickapp 分支,修改 package.json 文件。
git clone https://github.com/chameleon-team/cml-flexbox.git
cd cml-flexbox
git checkout master-quickapp
升级原有的 package 如下:
"chameleon-api": "^0.5.3",
"chameleon-bridge": "^0.2.0",
"chameleon-runtime": "0.1.4",
"chameleon-store": "0.0.3",
"chameleon-ui-builtin": "^0.4.0-mvvm.3",
"cml-ui": "^0.3.0-alpha.1",
新增引入的快应用 package 如下:
"cml-quickapp-api": "1.0.0",
"cml-quickapp-plugin": "1.0.0",
"cml-quickapp-runtime": "1.0.0",
"cml-quickapp-ui-builtin": "1.0.0",
"cml-quickapp-ui": "1.0.0",
"cml-quickapp-store": "1.0.0"
修改app.cml
修改 app.cml 文件,增加快应用 manifest.json 文件对应的配置
vim ~/cml-flexbox/src/app/app.cml
找到 <script cml-type="json">
开头的这部分
<script cml-type="json">
{
"wx": {
"window": {
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Chameleon",
"navigationBarTextStyle":"black"
}
},
"baidu": {
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTitleText": "Chameleon",
"navigationBarTextStyle": "black"
}
},
"alipay": {
"window": {
"defaultTitle": "Chameleon"
}
}
}
</script>
增加快应用需要的配置
<script cml-type="json">
{
"quickapp": {
"package": "com.application.demo", // 快应用包名
"name": "demo", // 快应用名称
"versionName": "1.0.0", // 版本名称
"versionCode": "1", // 版本代码
"minPlatformVersion": "1020", // 最小平台版本号
"icon": "../assets/images/chameleon.png", // 快应用logo
"features": [{ // 引用的快应用的能力
"name": "system.router"
},
{
"name": "system.webview"
},
{
"name": "system.prompt"
},
{
"name": "system.clipboard"
},
{
"name": "system.calendar"
},
{
"name": "system.device"
},
{
"name": "system.fetch"
},
{
"name": "system.file"
},
{
"name": "system.geolocation"
},
{
"name": "system.image"
},
{
"name": "system.media"
},
{
"name": "system.notification"
},
{
"name": "system.barcode"
},
{
"name": "system.sensor"
},
{
"name": "system.share"
},
{
"name": "system.shortcut"
},
{
"name": "system.storage"
},
{
"name": "system.vibrator"
},
{
"name": "system.network"
},
{
"name": "system.request"
},
{
"name": "system.audio"
},
{
"name": "system.volume"
},
{
"name": "system.battery"
},
{
"name": "system.brightness"
},
{
"name": "system.package"
},
{
"name": "system.record"
},
{
"name": "system.sms"
},
{
"name": "system.websocketfactory"
},
{
"name": "system.wifi"
},
{
"name": "system.contact"
}
],
"permissions": [{
"origin": "*"
}],
"config": {
"logLevel": "debug"
},
"display": {
"titleBarBackgroundColor": "#f2f2f2",
"titleBarTextColor": "#414141",
"titleBarText": "",
"menu": true
}
}
}
</script>
此配置对应快应用项目中的 manifest.json 文件,详细文档参考:manifest 文件
修改 chameleon.config.js 配置文件
1. 引入path模块
const path = require('path')
2. 增加 builtinNpmName 、 extPlatform 和 babelPath 配置
builtinNpmName: 'cml-quickapp-ui-builtin',
extPlatform: {
quickapp: 'cml-quickapp-plugin',
},
babelPath: [
path.join(__dirname,'node_modules/cml-quickapp-ui-builtin'),
path.join(__dirname,'node_modules/cml-quickapp-runtime'),
path.join(__dirname,'node_modules/cml-quickapp-api'),
path.join(__dirname,'node_modules/cml-quickapp-ui'),
path.join(__dirname,'node_modules/cml-quickapp-store'),
path.join(__dirname,'node_modules/cml-quickapp-mixins'),
path.join(__dirname,'node_modules/mobx'),
],
以上配置解释
builtinNpmName:自定义的内置 npm 包名称
extPlatform:配置扩展新端的编译插件
key:端标识
value:编译插件
npm:包名称
babelPath:要过 babel 处理的 npm 包
3. 导入基础样式
如果需要引入基础样式,需要增加 quickapp: true 的配置,参考 工程配置-baseStyle
baseStyle:{
wx: true,
web: true,
weex: true,
alipay: true,
baidu: true,
qq: true,
quickapp: true,
},
修改项目代码
1. 修改项目中相关包的引用
store 和 api 的引用:
chameleon-store 改为 cml-quickapp-store
chameleon-api 改为 cml-quickapp-api
import cml from "chameleon-api";
import store from "chameleon-store";
改为
import cml from "cml-quickapp-api";
import store from "cml-quickapp-store";
组件的引用 cml-ui 改为 cml-quickapp-ui
<script cml-type="json">
{
"base": {
"usingComponents": {
"c-actionsheet": "cml-ui/components/c-actionsheet/c-actionsheet"
},
}
}
</script>
改为
<script cml-type="json">
{
"base": {
"usingComponents": {
"c-actionsheet": "cml-quickapp-ui/components/c-actionsheet/c-actionsheet"
},
}
}
</script>
2. 多态组件在端的实现
如果存在某多态组件,以 poly-comp 为例
poly-comp.interface
poly-comp.web.cml
poly-comp.weex.cml
poly-comp.wx.cml
poly-comp.alipay.cml
poly-comp.baidu.cml
接入快应用的话,则需要增加一个 poly-comp.quickapp.cml
3. 多态接口在端的实现
如果存在某多态接口,以 poly-api.interface 为例
<script cml-type="interface">
type res = [String];
interface UnsupportedInterface {
getUnsupportApis(): res;
}
</script>
<script cml-type="web">
class Method implements UnsupportedInterface {
getUnsupportApis() {
return [];
}
}
export default new Method();
</script>
<script cml-type="weex">
class Method implements UnsupportedInterface {
getUnsupportApis() {
return ["设置页面标题", "WebSocket", "地理位置"];
}
}
export default new Method();
</script>
<script cml-type="wx">
class Method implements UnsupportedInterface {
getUnsupportApis() {
// 线上版微信小程序未配置demo请求的域名为可信域名,发版时去掉'网络请求'
// return ['网络请求', 'WebSocket'];
return [];
}
}
export default new Method();
</script>
<script cml-type="alipay">
class Method implements UnsupportedInterface {
getUnsupportApis() {
return ["启动参数", "beatles-bridge能力"];
}
}
export default new Method();
</script>
<script cml-type="baidu">
class Method implements UnsupportedInterface {
getUnsupportApis() {
return ["beatles-bridge能力"];
}
}
export default new Method();
</script>
<script cml-type="qq">
class Method implements UnsupportedInterface {
getUnsupportApis() {
// 线上版微信小程序未配置demo请求的域名为可信域名,发版时去掉'网络请求'
// return ['网络请求', 'WebSocket'];
return [];
}
}
export default new Method();
</script>
需要增加在快应用端的实现
<script cml-type="quickapp">
class Method implements UnsupportedInterface {
getUnsupportApis() {
// 线上版微信小程序未配置demo请求的域名为可信域名,发版时去掉'网络请求'
// return ['网络请求', 'WebSocket'];
return [];
}
}
export default new Method();
</script>
快应用启动命令
快应用支持的命令有
cml quickapp dev
cml quickapp build
当你完成了以上的步骤之后,就可以在你的项目中执行 cml quickapp dev
进行快应用的开发了。在 CML 项目根目录 ~/cml-flexbox/
执行 cml quickapp dev
,会生成 dist/quickapp
文件夹,拷贝 /dist/quickapp
目录下所有文件到已经提前启动的快应用的项目根目录 ~/quickapp-demo/
,更新快应用代码,即可进行调试和预览。
cd ~/cml-flexbox
cml quickapp dev
cp -r dist/quickapp/* ~/quickapp-demo/
Bug & Tips
当前阶段的适配工作虽然已覆盖几乎所有 Chameleon 的功能特性,但受制于快应用和 Chameleon 之间存在的少许差异性,仍然存在一些尚未解决的问题,这些问题我们会在后续持续跟进和优化完善。
这些尚未完成的 feature 包括:
- 动画相关。Chameleon 的动画调用方式和快应用差异颇大,当前未进行适配。
- CSS 特性。受制于部分快应用的特性,诸如 box-sizing、box-shadow、white-space 等属性暂未支持。
- watch 能力。当前可以进行 cml-quickapp-store 作用域内的属性 watch,对普通属性则未生效。
后续快应用发展和规划
快应用后续会持续强化和完善基础能力,力求在体验上趋近原生 App,加速快应用商业变现,实现头部快应用开发者可盈利,并布局海外,初步实现在印度和东南亚地区业务落地。
网友评论