《HarmonyOS:领航者说》技术公开课来啦,大咖分享、实战解码,不容错过 了解详情
写点什么

Chameleon 支持字节跳动小程序

  • 2019-08-22
  • 本文字数:5212 字

    阅读完需:约 17 分钟

Chameleon支持字节跳动小程序

前言

Chameleon(简写 CML ) 团队秉承"一套代码运行多端,一端所见即多端所见"的初心,在最初支持 web weex wx 三端之后,凭借着多态协议设计思想,灵活的工程化配置,以及跨端标准协议, CML 团队可以很快的扩展新端,比如支付宝小程序和百度小程序。


对于字节跳动小程序,考虑到 CML 开源社区的比较活跃,以及很多同行有着极大的兴趣共建,内部讨论之后,一致决定由外部贡献者根据跨端标准协议去扩展字节跳动小程序,目前已经完成了支持字节跳动小程序的开发。


对于已有的 CML 的项目按照接入字节跳动小程序步骤,即可直接复用;


CML 官方的体验仓库包括:cml-demo 、cml-flexbox、cml-yanxuan、cml-todomvc


地址: https://github.com/chameleon-team


下载字节跳动小程序开发者工具:https://microapp.bytedance.com/docs/devtool/versionUpdate.html


clone 下来以上仓库之后,切换到 master-tt 分支,执行 cml tt dev,在开发者工具中即可预览效果;


以上项目在字节跳动小程序中的预览效果图如下:


那么具体该如何接入字节跳动小程序呢?

如何接入字节跳动小程序

  • 升级最新的 chameleon-tool


npm i chameleon-tool@0.4.0 -g
复制代码


  • 升级 npm 包,引入字节跳动小程序相关包。升级的包如下:


"chameleon-api": "^0.5.3","chameleon-runtime": "0.1.4","chameleon-store": "0.0.3","chameleon-ui-builtin": "^0.4.1","cml-ui": "^0.3.1"
复制代码


引入的新包如下:


"cml-tt-api": "0.2.3","cml-tt-plugin": "0.2.3","cml-tt-runtime": "0.2.3","cml-tt-store": "0.2.3","cml-tt-ui": "0.2.3","cml-tt-ui-builtin": "0.2.3"
复制代码

修改 chameleon.config.js 相关配置:

  1. 引入 path 模块


const path = require('path')
复制代码


  1. 新增配置


builtinNpmName: 'cml-tt-ui-builtin',extPlatform: {  tt: 'cml-tt-plugin',},babelPath: [  path.join(__dirname,'node_modules/cml-tt-ui-builtin'),  path.join(__dirname,'node_modules/cml-tt-runtime'),  path.join(__dirname,'node_modules/cml-tt-api'),  path.join(__dirname,'node_modules/cml-tt-ui'),  path.join(__dirname,'node_modules/cml-tt-store'),  path.join(__dirname,'node_modules/cml-tt-mixins'),  path.join(__dirname,'node_modules/mobx'),]
复制代码

修改项目代码

  1. 修改项目中相关包的引用


import cml from "chameleon-api";import store from "chameleon-store";<script cml-type="json">  {"base": {"usingComponents": {"c-actionsheet": "cml-ui/components/c-actionsheet/c-actionsheet"          },      }  }</script>
复制代码


改为


import cml from "cml-tt-api";import store from "cml-tt-stroe";<script cml-type="json">  {"base": {"usingComponents": {"c-actionsheet": "cml-tt-ui/components/c-actionsheet/c-actionsheet"          },      }  }</script>
复制代码


  1. 项目中开发者自定义的多态组件 以及 多态接口 都要增加字节跳动这一端的实现

  2. 详细教程参考:https://cmljs.org/doc/example/tt_miniapp.html

扩展字节跳动小程序日志

参与方:


  • 阿里影业 @怀虚

  • 主要负责 cml-tt-ui 和 cml-tt-runtime


-芒果 Tv @Jeany


主要负责 cml-tt-api


  • 滴滴普惠出行 @不懂小彬

  • 主要负责 cml-tt-ui-built 和 cml-tt-store

  • 滴滴普惠出行 @榮

  • 主要负责 cml-tt-plugin 和 cml-tt-mixins


以下适合有一定 CML 基础的人阅读。

了解扩展新端标准编译侧的 webpack 原理

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; })
复制代码


以上就是 CML 脚手架产生的树状结构图,递归传递给 cml-XX-plugin 来转义目标语法。

实现 cml-tt-plugin

目标:将 template、script、style 等节点编译成符合字节跳动小程序的语法,然后打包输出成符合字节跳动小程序的结构;


cml-tt-plugin: https://github.com/chameleon-team/cml-tt-sets/blob/master/packages/cml-tt-plugin/index.js


根据上面生成的构建图,贡献者在编译插件 cml-tt-plugin 中可以对构建图中所有节点(包括 js 节点 json 节点 style 节点 template 节点等)编译成符合要扩展的端的语法,然后在 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()    })    ......  }}
复制代码


更为详细的 开发编译插件的教程请参考:https://cml.js.org/doc/extend/start.html


以扩展字节跳动的 template 编译为例:


compiler.hook('compile-template', function(currentNode, parentNodeType) {// 部分template处理也需要用到optionsconst options = currentNode.extra;  currentNode.output = templateParser(currentNode.source, options)
})
复制代码


这个 templateParser 函数就是将 CML 协议下的模板语法 转化为符合字节跳动小程序的语法。



<view c-if="{{value}}"></view>
复制代码


转化为


<view tt:if="{{value}}"></view>
复制代码


模板编译的具体实现参考:


https://github.com/chameleon-team/cml-tt-sets/blob/master/packages/cml-tt-plugin/index.js


各个节点编译完之后,可以再 pack 阶段自定义打包,部分代码如下:


compiler.hook('pack', function(projectGraph) {  let hasCompiledNode = [];  let bootstrapCode = compiler.amd.getModuleBootstrap();  compiler.writeFile('/static/js/manifest.js', bootstrapCode);  let commonjsContent = `var manifest = require('./manifest.js');\n`;  commonjsContent += `var cmldefine = manifest.cmldefine;\n`;// 遍历节点  outputNode(projectGraph);  compiler.writeFile('/static/js/common.js', commonjsContent);//...})
复制代码


具体实现参考:


https://github.com/chameleon-team/cml-tt-sets/blob/master/packages/cml-tt-plugin/index.js

实现 cml-tt-runtime

目标:实现运行时,代理字节跳动小程序 App,Page,Component 方法以及生命周期。


cml-tt-runtime:https://github.com/chameleon-team/cml-tt-sets/tree/master/packages/cml-tt-runtime


运行时的主要作用是抹平各端的生命周期差异性,进行数据响应式绑定等 实现运行时的参考教程 :https://cml.js.org/doc/extend/runtime.html


这里以 page 实现逻辑为例:


// 编译时自动插入用户配置的运行时方法import {createPage} from 'cml-tt-runtime';createPage(exports.default);
复制代码


以上两行代码是在 mvvm-cml-loader 中插入的,具体实现参考源码:https://github.com/didi/chameleon/blob/0.3.x-alpah-merge-mvvm/packages/mvvm-cml-loader/selector.js


中对于 script 节点的处理;


我们只需要实现对应端的以下几个方法:createApp createPage createComponent


具体实现参考:


https://github.com/chameleon-team/cml-tt-sets/tree/master/packages/cml-tt-runtime/src/tt/instance


以 cml-tt-runtime 中的 createPage 实现为例:


https://github.com/chameleon-team/cml-tt-sets/tree/master/packages/cml-tt-runtime


cml-tt-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-tt-runtime/src/interfaces/createPage/index.jsimport createPgInterface from './index.interface';export function createPage(options) {  return createPgInterface.createPage(options)}
复制代码


cml-tt-runtime/src/interfaces/createPage/index.interface


//这里要将 chameleon-runtime中的 createPage接口 include 进来<include src="chameleon-runtime/src/interfaces/createPage/index.interface"></include><script cml-type="tt"> import {Page} from '../../tt'class Method implements createPageInterface {    createPage(options) {return new Page(options);    }  }
export default new Method();</script>
复制代码

实现 cml-tt-api

目标:基于跨端协议,实现字节跳动小程序对应的 API


cml-tt-api:https://github.com/chameleon-team/cml-tt-sets/tree/master/packages/cml-tt-api


实现 API 的部分特别简单,只需两步:


  • 第一:引入官方标准 interface 文件。

  • 第二:扩展实现新端,实现对应端的方法。


具体实现如下:


cml-tt-api/src/interfaces/alert/index.interface


// 引入官方标准interface文件<include src="chameleon-api/src/interfaces/alert/index.interface"></include>
// 扩展实现新端,实现对应端的方法<script cml-type="tt">class Method implements uiInterface { alert(opt, successCallBack, failCallBack) {let { message, confirmTitle} = opt; tt.showModal({title: confirmTitle,content: message,showCancel: false, success() { successCallBack(confirmTitle); }, fail(){ failCallBack(confirmTitle); } }); }}
export default new Method();</script>
复制代码

实现 cml-tt-store

目标:基于 mobx 实现一套响应式数据系统


cml-tt-store:https://github.com/chameleon-team/cml-tt-sets/tree/master/packages/cml-tt-store

实现 store 同样只需要两步:

  • 第一:引入官方标准 interface 文件。

  • 第二:扩展实现新端,实现对应端的方法。


//引入官方标准 interface 文件<include src="chameleon-store/src/interfaces/createStore/index.interface"></include>
<script cml-type="tt">
import createStore from '../../platform/tt'//扩展实现新端,实现对应端的方法class Method implements createStoreInterface { createStore(options) {return createStore(options) } }
export default new Method();</script>
复制代码


具体实现代码参考:https://github.com/chameleon-team/cml-tt-sets/blob/master/packages/cml-tt-store/src/platform/common/mini/index.js

实现 cml-tt-ui-builtin 和 cml-tt-ui

目标:UI 组件库是用来实现多端一致性的基础,参考原有的组件库实现,可以快速扩展出字节跳动小程序端的 UI 组件。


cml-tt-ui:https://github.com/chameleon-team/cml-tt-sets/tree/master/packages/cml-tt-ui


cml-tt-ui-builtin:https://github.com/chameleon-team/cml-tt-sets/tree/master/packages/cml-tt-ui-builtin


扩展新端组件教程参考:


https://cml.js.org/doc/extend/ui-builtin.html

共建成果

应社区内广大开发者的提议,CML 团队制定了一套 MVVM+ 的 协议标准,并且在此标准上,规定了 扩展新端标准流程 。随着越来越多的小程序厂商入局,CML 团队会带着"一套代码运行多端,一端所见即多端所见"的初心,继续支持各个小程序的开发和应用。


2019-08-22 08:094205

评论

发布
暂无评论
发现更多内容

龙蜥社区 11 月运营大事件回顾

OpenAnolis小助手

活动 生态 龙蜥社区 11月 运营月报

App 长登录思考与实现part2

石君

App 信息安全 认证

SAP MM 为UB类型的STO执行VL10B,报错-没有项目类别表存在(表T184L NL 0002 V)-之对策

SAP虾客

SAP MM UB类型STO VL10B T184L

直播预告|PostgreSQL 技术内幕(四)执行引擎之Portal

酷克数据HashData

HA高可用软件大致有哪些?大众用的哪款?

行云管家

高可用 ha 高可用软件

堡垒机可以试用吗?哪款堡垒机可以?咨询电话多少?

行云管家

网络安全 信息安全 数据安全 堡垒机

更改 HIVE 表字段数据类型有哪些注意事项?

明哥的IT随笔

hadoop hive

基于分发与计算的GRTN全球实时传输网络

阿里云CloudImagine

互联网 科技 GRTN 全球实时网络传播 分发与计算

腾讯云数据库SaaS服务2022再升级 全面助力企业提升数据库运维能力

科技热闻

GaussDB(for Cassandra)新特性发布:支持Lucene二级索引,让复杂查询更智能

秃头也爱科技

PGL图学习项目合集&数据集分享&技术归纳业务落地技巧[系列十]

汀丶人工智能

神经网络 图神经网络 12月日更 11月月更 12月月更

Serverless Devs 重大更新,基于 Serverless 架构的 CI/CD 框架:Serverless-cd

Serverless Devs

Serverless Serverless Devs

降价背后,函数计算规格自主选配功能揭秘

Serverless Devs

Serverless 前端 函数计算FC

奇点云DataSimba R4.5发布关键更新,做到“可大可小可观测”

奇点云

如何通过C#/VB.NET将PDF转为Word

在下毛毛雨

C# PDF word 转换

MySQL从入门到实战讲解,京东T5大牛学习笔记分享,看完我哭了!

钟奕礼

Java 程序员 java面试 java编程

别再被小程序全页变灰给坑了

FE情报局

小程序 前端

动不动问原理,面试官你来讲讲Spring的原理?讲出来我给你开25K

钟奕礼

Java 程序员 java面试 java编程

GitHub狂飙30K+star面试现场,专为程序员面试打造,现已开源可下载

钟奕礼

Java 程序员 java面试 java编程

阿里P8面试官总结的《2023最新java面试题》,搞定90%以上的技术面

钟奕礼

Java 程序员 java面试 java编程

非结构化数据暴增,企业如何稳定高效的支撑日均百亿级访问

秃头也爱科技

Redis之String类型和Hash类型的介绍和案例应用

C++后台开发

redis 数据结构 hash 后端开发 C++开发

iOS SIGKILL 信号量崩溃抓取以及优化实践

百度Geek说

ios 12 月 PK 榜 崩溃日志

并发编程详解:十三个工具类,十大设计模式,从理论基础到案例实战

钟奕礼

Java 程序员 java面试 java编程

拿到8000元的火焰杯比赛奖金,感谢霍格沃兹测试开发学社

测吧(北京)科技有限公司

软件测试比赛

Ansible最佳实践之 AWX 使用 Ansible 与 API 通信tags

山河已无恙

12月月更

Ansible最佳实践之 AWX 创建管理项目的一些笔记

山河已无恙

12月月更

低代码领域:发展路径、市场规模及未来趋势洞察!

优秀

低代码

React 之元素与组件的区别

冴羽

JavaScript react.js 前端 前端框架 React

OneFlow源码解析:自动微分机制

OneFlow

人工智能 深度学习 框架学习

Java jar 如何防止被反编译?代码写的太烂,害怕被人发现

小小怪下士

Java 程序员 反编译

Chameleon支持字节跳动小程序_语言 & 开发_王梦君_InfoQ精选文章