Skip to content

RN与UNI小程序混编落地

主要包含

  1. RN小程序SDK集成
  2. 小程序业务开发
  3. 小程序更新发布更新流程

一、环境

node 16.16.0 nvm

@vue/cli 4.5.15

npm install @vue/cli@4.5.15 -g

hbuildX 3.5.3 (去官网找历史版本) https://hx.dcloud.net.cn/Tutorial/HistoryVersion

cli中关键版本 以下是典型, 类似 2.0.1-35320220729002的版本 ,根据官方npm包的发布,

"@dcloudio/vue-cli-plugin-hbuilderx": "2.0.1-35320220729002",

"@vue/cli-plugin-babel": "~4.5.15",

"@vue/cli-service": "~4.5.15",

二、项目中集成SDK

切换到公司的源
yarn add  xm-react-native-uni
cd ios && pod install

安卓要在 MainApplication.java 中加上防止多次初始化的方法,见example

image-20221008140004164

ios要在AppDemegate.mm

#import <DCUniMP.h>


  NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:launchOptions];
   // 设置 debug YES 会在控制台输出 js log,默认不输出 log,注:需要引入 liblibLog.a 库
   [options setObject:[NSNumber numberWithBool:false] forKey:@"debug"];
   [DCUniMPSDKEngine initSDKEnvironmentWithLaunchOptions:options];

image-20221012181511304

三、使用

  1. RN中要在启动时调用initialize 进行SDK初始化

    Uni.initialize({
      items: [{ title: '标题', key: 't1' }],
      capsule: true,
      fontSize: '16px',
      fontColor: '#000',
      fontWeight: 'normal',
    })
      .then((res) => {
        console.log('initialize', res);
      })
      .catch((e) => {
        console.log('initialize:Error', e);
      });
  2. 设置启动屏

    class SplashView extends React.Component<{ appid: string }> {
      render() {
        return (
          <View
            style={{
              flex: 1,
              backgroundColor: 'blue',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            <Text>启动屏:{this.props.appid}</Text>
          </View>
        );
      }
    }
    
    Uni.setSplashView(SplashView);
  3. 监听事件

      useEffect(() => {
        let subs: EventSubscription[] = [];
        // 监听小程序胶囊点击事件
        subs.push(
          Uni.onMenuClick((key) => {
            console.log('点击胶囊', key);
          })
        );
        // 监听小程序关闭事件
        subs.push(
          Uni.onAppClose((appid) => {
            console.log('onAppClose', appid);
          })
        );
        // 监听小程序发送的数据
        subs.push(
          Uni.onEventReceive((data) => {
            console.log('RN收到数据', data);
            if (data.type === 'callback') {
              if (data.data.cb === 'downloadUpdateVersion') {
                downloadUpdateVersion(data.data.appid);
              }
            }
            if (data.type === 'callback') {
              if (data.data.cb === 'launch') {
                relaunch({ appid: data.data.appid, path: data.data.path });
              }
            }
          })
        );
        return () => {
          subs.forEach((sub) => sub.remove());
        };
      }, []);
  4. App更新小程序流程

    • 第一次打开小程序,远程下载最新的,存储小程序versionInfo到本地
    • 再次打开小程序,小程序调用接口checkVersion,拿到最新的与本地的比对,versionCode,versionName, fileId,如果有更新,通知RN下载小程序,下载完毕,通知小程序弹框提醒,点击确认更新,重启小程序
  5. RN && 小程序 通信

    • RN的代码都要引入 xm-react-native-uni

      import * as Uni from 'xm-react-native-uni';
    • RN通知小程序

         RN通知小程序(RN代码)
         Uni.sendEvent('downloadUpdateVersion', {
                  isSuccess:true,
                  msg:'检查版本下载完成',
                  versionInfoData: result,
                });
      
          小程序接收(小程序代码)
            uni.onNativeEventReceive((event, dataStr) => {
                //因为是UNI的,所以没统一转
                const data = JSON.parse(dataStr)
      
      
            });
            接收到的数据为JSON,数据结构
            {
              "event":"downloadUpdateVersion",
              "data": {
                  isSuccess: true,
                  msg:: '检查版本下载完成',
                  versionInfoData: result,
                }
            }
    • 小程序通知RN

      小程序发送(小程序代码)
      uni.sendNativeEvent('unimp-event', {
      					type: 'callback',
      					data: {
      						cb: 'downloadUpdateVersion',
      						appid: plus.runtime.appid
      					}
      	});
      
      RN接收(RN代码)
       Uni.onEventReceive((data) => {
              console.log('RN收到数据', data);
              if (data.type === 'callback') {
                if (data.data.cb === 'launch') {
                  relaunch({ appid: data.data.appid, path: data.data.path });
                }
              }
       })
       
       接收的数据已经处理,js object 
             {
      					type: 'callback',
      					data: {
      						cb: 'downloadUpdateVersion',
      						appid: plus.runtime.appid
      	         }
      	      }

四、小程序框架

  1. 开发

下载模板(目前还没配套cli)

git clone http://gitlab.guojutech.net/xmgj/xm-uni-mini.git

修改项目名,比如package.json

打开manifest.json

  1. 目录结构
xm-uni-mini
	- deploy        部署脚本
	- dist					打包的内容,运行内容
	- node_modules  依赖
	- public        公共资源
	- src           业务(主要编写代码的地方)
	  - api					公共请求
	  - common			公共样式,工具类,环境配置,缓存标识等
	  - components	公共业务组件
	  - pages				业务页面
	  - static      业务静态资源
	  - store				vuex
	  - uni_modules	uni的组件
		- App.vue			主组件
		- main.js			程序入口
		- pages.json	添加页面
		- uni.css			主题配置(自带的)

重点了解页面,请求,环境配置,公共组件,公共样式,vuex

  • 页面

    可以通过hbuildx启动小程序模式(效果好),或者浏览器模式(方便)

  • 请求api request.js

    rn传递参数启动小程序

    Uni.launch({
            appid: appid,
            params: {
              env: 'test',
              tokenId: 'c688dd49-9fcb-41ae-b500-bbe5ece9c0ba',
            },
     });

    小程序平时开发,和嵌入App时是走的不同路径

    try {
    	// 获取APP传过来的参数
    	const appArguments = JSON.parse(plus.runtime.arguments)
    	// 获取环境
    	baseUrl = _.getBaseUrl(appArguments.env)
    	// 获取tokenId
    	tokenId = appArguments.tokenId || ""
    } catch (e) {
    	if (process.env.NODE_ENV === 'development') {
    		console.log('开发环境');
    		baseUrl = config.APP_REQUEST_DOMAIN_PREFIX_SELF
    	} else {
    		console.log('生产环境');
    		baseUrl = config.APP_REQUEST_DOMAIN_PREFIX_PRO
    	}
    }
  • 配置 config.js (开发时,注意切换)

    // 生产
    export const APP_REQUEST_DOMAIN_PREFIX_PRO = "https://apiapp.guojutech.net/";
    // stage
    export const APP_REQUEST_DOMAIN_PREFIX_STAGE = "https://apiapp-stage.guojutech.net/";
    // uat
    export const APP_REQUEST_DOMAIN_PREFIX_UAT = "http://api.uat.guojutech.net/";
    // test
    export const APP_REQUEST_DOMAIN_PREFIX_TEST = "http://api.test.guojutech.net/";
    // dev
    export const APP_REQUEST_DOMAIN_PREFIX_DEV = "http://api.dev.guojutech.net/";
    // 单独开发时赋值给上面几种环境即可
    export const APP_REQUEST_DOMAIN_PREFIX_SELF = APP_REQUEST_DOMAIN_PREFIX_TEST;
  • Components 业务组件 uni_modules uni官网组件 (建议看一下官网,然后demo)

  • customer.scss 业务公共样式 uni.css 自带的样式,可以了解一下,在App.vue中引入

    <style>
    	/*每个页面公共css */
    	/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
    	/* uni.css - 通用组件、模板样式库,可以当作一套ui库应用 */
    	@import './common/uni.css';
    	/* 自定义全局样式 */
    	@import './common/customer.scss';
    </style>
  • vuex

    vuex常规结构,编写方式

    取值

    全局注入了 this.$store

    mapState, mapActions

五、 发布

jenkins,web

  • 测试的时候,直接传代码,然后打包,不用修改
  • 发布的时候,则要先改版本号,版本名,选择jenkins,web打包均可

六、待完善事项

  1. sdk相关扩展的完善,比如相机,相册等

  2. 小程序业务框架的组件库提取搭建,公共请求的优化等等(xm-uni-mini模板主要去优化src里面的内容,外面的结构请慎动)

上次更新于: