首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >hippy-react 支持转小程序

hippy-react 支持转小程序

原创
作者头像
melodyren
修改2020-07-16 22:10:52
2.4K0
修改2020-07-16 22:10:52
举报
文章被收录于专栏:Hippy 跨端框架Hippy 跨端框架

背景

Hippy-react 官方并没有提供同构小程序的方案;

思考:我们技术栈hippy-react,其他业务也有同构小程序的需求,是否可以支持项目一键转小程序,减少重复开发;

目标:同构

项目仓库:https://git.code.oa.com/melodyren/wx_hippy

基础框架选型

这里调研了业界开源框架;最主要的区别是 DSL;大多数遵循React语法或VUE语法;

我们团队是基于Hippy-React开发,语法是react;

关于vue语法相关框架uiapp, mpvue ,wepy不在我们考虑接入范围内;

我们主要对比了二个React语法框架:alita和taro;

image
image
  1. Alita业内首个React Native转微信小程序引擎;Hippy React 基本兼容 React Native 语法;
  2. 组件标签: alita对齐hippy react是rn标签,taro是小程序标签;
  3. 样式规范: alita对齐hippy react是stylesheet,taro是sass,less;
  4. Alita 编译+运行时处理,(是基于组件的 template,动态 “递归” 渲染整棵树), 对JSX语法限制小; taro 2.0之前版本对JSX有诸多限制,比如暂不支持render()之外定义JSX;但2.0版本也改为了编译+运行时; 这里之前有输出一篇文章:http://km.oa.com/group/38202/articles/show/415870 有兴趣可以查阅;
  5. 包大小:alita 非常纯碎,只做了转小程序功能;alita包更小,更有优势;
  6. alita分包,原生组件,第三方组件都支持;

通过对比,alita更契合我们业务,改动最小;对项目倾入性更小;

当然如果比github start数和稳定性,taro更有优势;但基于taro改造工程量有点大哦;

!!!基于alita进行改造,适配hippy-react;那么如何转呢?

整体架构

image
image
  1. 整体要有hippy-react 开发体验;
  2. 组件和API对齐hippy官方API;
  3. 支持项目接入,优化webpack构建流程;
  4. 完成基础库同构;(此处是业务侧逻辑同构,每个业务侧不同);
  5. 支持第三方组件接入,比如trtc-room 是腾讯云官方提供的音视频组件,支持分平台处理;
  6. 性能优化;

如何做到组件/API对齐呢?

Alita对Hippy组件支持情况

- [x] View

- [x] Text

- [x] Image

- [x] TextInput

- [x] ScrollView

- [ ] ListView

- [ ] Animation

- [ ] AnimationSet

- [ ] ViewPage

- [ ] Navigato

- [ ] RefreshWrappe

- [x] Modal

其中View,Text,Image,TextInput,ScrollView,Modal,Alita均有提供,属性和方法稍加修改基本可以做到支持;

ViewPager,ListView,RefreshWrapper,Navigator需要额外扩展@areslabs/wx-react-native 去支持;

Animation,AnimationSet是Hippy提供的动画方案。Hippy的动画则是完全由前端传入动画参数,由终端控制每一帧的计算和排版更新,减少了js端与native端的通信次数,因此也大大减少动画的卡顿。而RN动画是前端驱动,状态值由前端计算,并且通过jsbridge传入终端实现动画。API对前端入门友好,并且方便状态管理。由于二端实现差异有点大,目前还未实现同构;

通过修改后对Hippy组件支持情况

- [x] View

- [x] Text

- [x] Image

- [x] TextInput

- [x] ScrollView

- [x] ListView

- [ ] Animation

- [ ] AnimationSet

- [x] ViewPage

- [x] Navigato

- [ ] RefreshWrapper(包装在listview)

- [x] Modal

Alita对Hippy模块支持情况

常用基本已支持;平台相关的组件,均没有实现

- [x] AsyncStorage

- [ ] BackAndroid 微信小程序限制

- [ ] Clipboard

- [x] Dimensions

- [ ] NetworkModule

- [ ] NetInfo

- [x] PixelRatio

- [x] Platform

- [x] Stylesheet

- [x] Timers

修改后对Hippy模块支持情况

- [x] AsyncStorage

- [ ] BackAndroid 微信小程序限制

- [ ] Clipboard

- [x] Dimensions

- [ ] NetworkModule

- [x] NetInfo

- [x] PixelRatio

- [x] Platform

- [x] Stylesheet

- [x] Timers

由于alita提供的组件和hippy-react内置组件并不完全对齐;我们将alita 开源项目拉取下来到我们仓库地址进行维护,并对wx-react-native模块进行修改,拉齐组件和api;完成同构;

(正常情况下:只要hippy-react 组件和api 有对应的小程序组件和api,我们就可以完成重构);

左侧是需要支持组件,右侧是对应小程序组件;

image
image

这里是如何做到hippy 组件 和 小程序组件对齐的呢?我大概画了一下流程图:

image
image

小程序的js文件,无法直接在React层运行,需要提供一个上层Viewpager的代理,这个代理将代替小程序Viewpager组件在React层运行;

第一步:一般需要在对应包的package.json文件的wxComponents 字段指定,建立联系;

第二步:继承自RNBaseComponent,提供上下两层交互数据能力,diff算法拿到变更传给小程序setData;事件回调点击事件触发了小程序事件再传给react运行环境;

Alita框架运行原理

官方文档:https://areslabs.github.io/alita/

image
image

Alita 转小程序整体流程:webpack打包到js文件,js文件经过alita-loader处理收集信息info, 然后经过babel-loader 处理,最后通过webpack的alita-plugins(多个)生成小程序文件(wxml/wxss等)

Alita 的整体架构借鉴了 ReactNative,其上层存在一个为小程序定制的 mini-react,底层是负责实际渲染的小程序原生代码。而中间存在一个两层互相联系的 bridge。

image
image

mini-react 负责运行所有 React 代码逻辑,包括递归的构建组件树结构,创建组件实例,执行组件对应生命周期,context 计算等等。其最终将生成一份描述小程序视图的数据。这份数据通过 bridge 模块传递到底层小程序。底层小程序实例调用 setData 方法把数据刷给自身,完成渲染。

如何集成到项目工程呢?

项目目录规范 - 接入方便,只须在之前项目目录新增打包配置文件alita.config.js 和小程序入口文件index.wx.js

image
image

alita.config.js 说明:

const path = require("path");

module.exports = {
  name: "HelloWorldExpo",//生成的微信小程序项目名
  appid: "wxc88f41e36c417bff",//调试小程序的appid,由微信申请而来
  entry: "./projects/HelloWorldExpo/index.js",//定义页面的入口文件
  output: "./output/wx-dist/HelloWorldExpo",//输出目录,小程序生成代码输出目录
  include: [ //符合alita规范,直接转化的组件,alita使用的是webpack打包的方式,会使用alita-loader去解析
    path.resolve("./projects/HelloWorldExpo/"), // 指定项目
    //path.resolve("./library/components/CountPane.js"), //可以引入项目外的通用组局
    // path.resolve("node_modules", "@areslabs", "hello-rn")//可以引入npm包
  ],
  resolve: {
    alias: { //别名
      // "@tencent/hippy-react": "@areslabs/wx-react-native"
    },
    // symlinks: false
  },
  miniprogramComponents: { // 第三方组件
    // "trtc-room": "/weixin/components/trtc-room/trtc-room"
  }
};

符合alita规范,直接转化的组件,可在配置文件include 添加路径, alita使用的是webpack打包的方式,会使用alita-loader去解析;

如果是对小程序内置组件或者对小程序自定义组件的使用,都是只会在小程序平台生效,所以需要平台判断,和ReactNative一样,一般有两种方式: 文件内判断和建立平台文件

  1. 文件内判断 if (Platoform.OS === 'wx') { return 小程序的view // <-- 直接使用小程序组件 } else { return Hippy-React的View // <-- 使用Hippy-React组件 }
  2. 建立平台文件:(建议差异比较大的) 建立平台文件的方式,即建立单独的小程序.wx后缀文件,比如Map.wx.js

入口文件

React 组件会被转化为 wxml/wxss/js/json 4个文件, 这里有一个例外:入口文件。入口文件里面定义了所有的页面,由于小程序的页面必须预先定义在 app.json 文件,json文件是静态的,无法在运行时处理,因此我们必须在转化的时候就识别出所有的页面,所以对于入口文件的文件要求是足够的静态,为了减少错误,尽量不要在入口文件处理其它逻辑,仅将入口文件用来定义路由页面。

详情请看官方文档: https://areslabs.github.io/alita/入口文件.html

import React, { PureComponent } from "react";
import { Router, Route } from "@areslabs/router";
import Room from "./pages/Room";
// import Player from "./components/Room/Player";
export default class App extends PureComponent {
  render() {
    return (
      <Router
        wxNavigationOptions={{
          // navigationBarTitleText: "",
          navigationBarBackgroundColor: "#291B54"
          // navigationBarTextStyle: "black"
        }}
        navigationOptions={{
          title: "相亲房间"
        }}
      >
        <Route key="Room" component={Room} />
        {/* <Route key="Player" component={Player} /> */}
      </Router>
    );
  }
}
项目运行:

类似wepack执行,接入了yargs,支持三种模式,最终都是用alita-core去打包;

# 开发模式 
dating run-wx —dev [projectname]
# 打包模式 
dating run-wx --build [projectname] 
# 分析包模式
dating run-wx —analyzer [projectname]
const argv = yargs
    .command(COMMAND.RUN_WX, "运行 wx 环境", function(yargs) {
      var _argv = yargs
        .reset()
        .option("dev", {
          alias: "dev",
          demand: false,
          describe: "是否开发环境",
          type: "boolean"
        })
        .option("build", {
          alias: "build",
          demand: false,
          describe: "是否编译环境",
          type: "boolean"
        })
        .option("analyzer", {
          alias: "analyzer",
          demand: false,
          describe: "分析包",
          type: "boolean"
        }).argv;
      if (_argv._ && _argv._[1]) {
        _argv.entry = _argv.e = _argv._[1];
      }
      process.argv.push("--config");
      process.argv.push("./projects/" + _argv.entry + "/alita.config.js");
      require("@tencent/alita-core/lib/index");
    })

微信小程序的体积是有限制的,“代码体积小于 2M,分包 8M”。借助webpack的BundleAnalyzerPlugin插件,只需要在执行时候添加 --analyzer 参数即可;

image
image

总结:Alita是基于RN转小程序,hippy-react和RN 的差异主要是在组件和api,站在巨人的肩膀上,我们很容易实现hippy-react转小程序;集成到工程需要看一下源码,做相对应改造;

目前K歌轻缘相亲做了简单尝试,欢迎大家体验(完整流程是下载相亲APP,打开相亲房间,分享相亲房间到微信,可以在微信内观看直播相亲哦)

image
image

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 基础框架选型
  • 整体架构
  • 如何做到组件/API对齐呢?
    • Alita对Hippy组件支持情况
      • 通过修改后对Hippy组件支持情况
        • Alita对Hippy模块支持情况
          • 修改后对Hippy模块支持情况
            • Alita框架运行原理
            • 如何集成到项目工程呢?
              • alita.config.js 说明:
                • 入口文件
                  • 项目运行:
                • 总结:Alita是基于RN转小程序,hippy-react和RN 的差异主要是在组件和api,站在巨人的肩膀上,我们很容易实现hippy-react转小程序;集成到工程需要看一下源码,做相对应改造;
                相关产品与服务
                云开发 CloudBase
                云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档