前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >kbone,十分钟让 Vue 项目同时支持小程序

kbone,十分钟让 Vue 项目同时支持小程序

作者头像
极乐君
发布2020-03-25 15:42:18
3.1K0
发布2020-03-25 15:42:18
举报
文章被收录于专栏:极乐技术社区

微信小程序开发过程中,许多开发者会遇到 小程序 与 Web 端一起的需求,由于 小程序 与 Web 端的运行环境不同,开发者往往需要维护两套类似的代码,这对开发者来说比较耗费力气,并且会出现不同步的情况。

小程序作为web的配套必需品,已经成为开发者不可避免的工作。多终端、多形态的开发无疑徒增工作量,费力不讨好。Kbone 就是一个致力于微信小程序和 Web 端同构的解决方案。一套代码同时开发完微信小程序以及web端。

基本结构

首先,我们来看下一个基本的 kbone 项目的目录结构(这里的 todo 是基于 Vue 的示例, kbone 也有 React , Preact , Omi 等版本,详情可移步 kbone github )。

因为 kbone 是为了解决 小程序 与 Web 端的问题,所以每个目录下的配置都会有两份(小程序 与 Web 端各一份)

入口

不管是 小程序 端还是 Web 端,都需要入口文件。在 src/index 目录下, main.js 为 Web 端用主入口, main.mp.js 则为 小程序 端用主入口。

当然,Web 端会比 小程序 多一个入口页面,即 index.html (位于根目录下)。

下面两段代码分别是 小程序端 入口与 Web 端入口的代码,可以看到 小程序端的入口代码封装在 createApp 函数里面(这里固定即可),内部会比 Web 端多一个创建 app 节点的操作,其他的基本就是一致的。

todo.vue

在上面的入口图可以看到,源码目录中,除了入口文件分开之前,页面文件就是共用的了,这里直接使用 Vue 的写法即可,不用做特殊的适应。

配置

写完代码之后,我们要怎么跑项目呢?这时,配置就派上用场啦。

Web 端配置为正常的 Vue 配置,小程序端配置与 Web 端配置的唯一不同就是需要引入 mp-webpack-plugin 插件来将 Vue 组件转化为小程序代码。

构建代码

接着,我们需要构建代码,让代码可以运行到各自的运行环境中去。构建完成后,生产代码会位于 dist 目录中。

小程序端 的构建会比 Web 端的构建多一个步骤,就是 npm 构建。

进入 dist/mp 目录,执行 npm install 安装依赖,用开发者工具将 dist/mp 目录作为小程序项目导入之后,点击工具栏下的 构建 npm ,即可预览效果。

效果

最后,我们来看一下 todo 的效果。kbone 初体验,done~

todo 代码可到 kbone/demo13 自提。

具体方案实现

接下来就来探讨下具体方案的实现。

社区 Web 端是基于 Vue 实现的,使用了 Vue-router、Vuex 等插件。Vue 想必大家挺熟悉的了,它是市面上一款非常流行的 Web 框架,提供组件化等特性,其原理大致如下:

Vue 模板可以认为是一种附加了一些特殊语法的 HTML 片段,一般来说一份 Vue 模板对应一个组件,在构建阶段编译成调用 Dom 接口的 JS 函数,调用此 JS 函数就会创建出组件对应的 Dom 树片段进而渲染到浏览器上。小程序里是支持运行 JS 的,但是这里用到的 Dom 接口和渲染到浏览器上的功能小程序不具备,所以无法直接将 Web 端社区代码移植到小程序中。原因就在于小程序为了安全和性能而采用了双线程的架构,运行用户 JS 代码的逻辑层是一个纯粹的 JSCore,没有任何浏览器相关的实现,这里得想办法将 Web 端代码转成小程序代码。

业界常见做法:将 Vue 模板直接转成小程序的 WXML 模板

那么问题来了,如何将 Vue 代码转成小程序代码?这里先看下业界常见的做法:将 Vue 模板直接转成小程序的 WXML 模板。

使用做法相当于抛弃了浏览器中建 Dom 树的过程,而是直接交由小程序来对模板进行编译创建出小程序的模板树,进而渲染到小程序页面中。

一般来说这个做法对于普通场景是够用的,但是对于一些更复杂的场景就很不好处理了,比如社区中的一个简单例子:社区帖子详情展示富文本内容,点击内容中的图片可预览。

这主要是因为 Vue 模板和 WXML 模板的语法并不是直接对等的,Vue 的特性设计也和小程序的设计无法划等号,这自然就导致了部分 Vue 特性的丢失。比如像 Vue 中的 v-html 指令、ref 获取 Dom 节点、过滤器等就通通用不了。当然不止是 Vue 自身的特性,一些原本依赖 Dom/Bom 接口的 Vue 插件也无法使用,比如 Vue-router 等,而这些正是社区高度依赖的,在不对社区代码做大范围改造的话是无法使用此方案的。

此路不通,那还有其他的方法么?

换个思路:做一个适配层

答案是有的,这里我们就得换一种思路来解决这个问题。回到最初的点上,我们无法将 Web 端代码移植到小程序中是因为小程序没有 Dom 接口,那么我们想办法做出一个适配层,将这个差异给抹掉不就行了么?

有了想法就要实施,仿造出 Dom 接口并不难,事实上在 Nodejs 端就有人做过类似的事,比如 jsDom 这个库的实现,让我们可以在没有真实浏览器环境下可以对一些依赖 Dom 接口的 Web 端代码进行测试。

仿造了 Dom 接口给 Vue 调用,进而创建出了仿造 Dom 树。根据前面提到的小程序架构,用户的 JS 代码是执行在逻辑层的,也就是说我们创建出的 Dom 树也是存在与逻辑层的内存之中,接下来要解决的难题是如何将这棵 Dom 树渲染到小程序页面中。

这里需要先简单介绍一下小程序的渲染原理:小程序的双线程架构,逻辑层会执行用户的 JS 代码进而产生一组数据,这组数据会发往视图层;视图层接收到数据后,结合用户的 WXML 模板创建出组件树,之后小程序再将组件树渲染出来。这里的组件树和 Dom 树很类似,只是它是由官方内置组件或自定义组件拼接而成而不是 Dom 节点。这里我们能不能将仿造出来的 Dom 树映射到小程序的组件树上?

小程序组件树是根据 WXML 模板创建出来的,而仿造 Dom 树结构是不稳定的,我们无法提前预知它会生成什么样的结构,也就无法提前准备后可以描述任意 Dom 树的 WXML 模板,除非直接将 Vue 模板转换成 WXML 模板,但这样又绕回前面的问题上了。

小程序组件树中的组件有两种:内置组件和自定义组件,内置组件是由官方提供的如 video、map 这样的组件,而自定义组件是一种支持由用户利用现有组件自行组装的组件,能否利用它来做些什么?

使用 Web 端概念来做个简单解释,内置组件就像是 div、span 这些 HTML 标签,而自定义组件就像是 Web 中的 Vue 组件。Vue 组件可以将 HTML 标签以及其他的 Vue 组件进行组装,自定义组件同理,主要用于功能模块的抽象、封装和复用。不过自定义组件有个很奇妙的特性,它支持自引用,也就是说它可以自己引用自己来进行组装。

自定义组件可以自己引用自己,那么我们就可以利用这个特性来进行递归创建组件,进而创建出一棵组件树:

比如上图的例子,我们封装了一个 custom-dom 组件,这个组件里面也使用了 custom-dom 组件用于渲染子组件。那么只要我们执行一下 setData,把 children 数据传递过去就可以创建出子组件,子组件本身也是 custom-dom 组件,它同样可以执行这个逻辑把各自的子组件创建出来,这样就实现了组件的递归创建,只要我们拥有完整的 Dom 树结构,就可以创建出相对应的一棵组件树。

这里递归的终止条件是遇到特定节点、文本节点或者孩子节点为空。然后在创建出组件树后,将 Dom 节点和自定义组件实例进行绑定以便后续的 Dom 更新和操作即可。

我们将其归纳为两个模块:仿造接口和自定义组件。正因为这个方案是通过提供适配器的方式来仿造出 Web 环境,所以用户代码不需要做任何魔改,大部分特性都可以继续使用不需要被删减,比如 vue-router、window.location 操作等。

原本 Web 端代码是基于 Vue 来搭建的,其中还用到了诸多插件/库,如 Vue-router、Vuex、Markdown-it 等,同时还支持了服务端渲染。但是不管 Web 端是怎么实现的,底层终究是调浏览器的那些接口,所以对于用户层面的代码我们不做任何调整,只是将浏览器那一层替换掉即可。

整个构建流程是基于 Webpack 来实现的,使用 Kbone 构建出小程序代码也是基于 Webpack 来实现,只需要在原本 Web 端构建流程上实现一个 Webpack 插件,在构建原本 Web 端代码到小程序端时追加 Kbone 和一些小程序相关的代码即可。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极乐技术社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本结构
  • 具体方案实现
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档