React-native JS运行环境。判断运行环境

  • 前提

    通常我在公司做Rn开发。主要是做组件开发,包括业务组件。项目的框架。全局处理。
    
    今天遇到一个问题:就是在使用可触控范围时,经常出现可点击范围过小问题。
    
    解决思路:在原有的可点击组件上,如果可控范围比较小,就在原有props增加调试属性(这里只是显示简单的边框 来提醒其他开发者的注意)。
    
    难点:
    	在测试过程中 如果测试人员发现边框问题,肯定会提出问题。这里仅仅希望Rn开发人员看到,并且修改。
    	思路: 在开启远程调试时开启高亮提醒(测试人员一般都不会开启chrome远程调试)
    
  • 解决思路

    • 开启debugger 都需要摇一摇 开启debugger

    • 查看 ios | android 的源码可以发现一种可行方案 就是自己编写原生代码提供给js使用

      • android DevInterndSetting.java
      • ios RCTDevSetting.m
      • 是否开启远程调试 可以通过属性查看
    • 我们进行调试都会在chrome浏览器中另外开启一个窗口

    • 查看 http://localhost:8081/debugger-ui/ 源码

      • 测试发现 开启远程调试 就会连接WS
      function connectToDebuggerProxy() {
      	const ws = new WebSocket('ws://' + window.location.host + '/debugger-proxy?role=debugger&name=Chrome');
      	let worker;
      	function createJSRuntime() {
      	  worker = new Worker('debuggerWorker.js');
      	  worker.onmessage = function(message) {
      	    ws.send(JSON.stringify(message.data));
      	  };
      	  window.onbeforeunload = function() {
      	    return 'If you reload this page, it is going to break the debugging session. ' +
      	      'You should press' + refreshShortcut + 'in simulator to reload.';
      	  };
      	  updateVisibility();
      }
      function shutdownJSRuntime() {
      
      }
      function updateVisibility() {
      
      }
      ws.onopen = function() {
        
      };
      ws.onmessage = async function(message) {
            if (!message.data) {
              return;
            }
            const object = JSON.parse(message.data);
      
            if (object.$event === 'client-disconnected') {
              shutdownJSRuntime();
              Page.setState({status: {type: 'disconnected'}});
              return;
            }
            if (!object.method) {
              return;
            }
      
            if (object.method === 'prepareJSRuntime') {} else if (object.method === '$disconnected') {} else if (object.method === 'executeApplicationScript') {} else {}
          };
          ws.onclose = function(error) {
          };
      }
      
  • JS运行环境总结

    • 开启远程调试
      在这里插入图片描述

      • 1:chorme 打开网页
      • 2:手机打开App 开启远程调试 连接网页Ws 传递参数
      • 3:chrome网页连接 react-native服务器 加载js代码 运行
      • 4:chrome保持和手机通讯 ==>React-native手机环境 展示页面
    • 不开启远程调试
      在这里插入图片描述

      • 1:连接React-native代码服务器
      • 2:手机本地的js运行环境运行 react - js代码
      • 3:js环境和原生环境通讯 UI展示
  • 解决

    	提供判断js运行环境来判断是否开启远程调试
    
    /**
     *  react-native JS代码运行环境
     */
    export const EnvirType = {
        /**
         * WIndow 浏览器 运行环境
         */
        WINDOWS: "win",
        /**
         * MAC 浏览器 运行环境
         */
        MACINTOSH: "mac",
        /***
         * Linux 浏览器 运行环境
         */
        LINUX: "linux",
        /***
         * ios 浏览器  运行环境
         */
        IOS: "iOS",
        /**
         * 安卓 浏览器 运行环境
         */
        ANDROID: "Android",
        /**
         * 黑莓 运行环境
         */
        BLACKBERRY: "bb",
        /***
         * Win iphone 运行环境
         */
        WINDOWS_PHONE: "winphone",
        /**
         * React-Native 运行环境
         * 直接运行在手机上的React-native环境
         */
        REACTNATIVE: "react-native"
    }
    /**
     * 是否为 rn 代码
     */
    export function isReactNative() {
        let GLOBAL = global || window;
        return GLOBAL && GLOBAL.ReactNative && GLOBAL.ReactNative.NativeModules
    }
    /**
     * 是否开启远程debugger
     */
    export function isStartReactRemoveDebugger() {
    
        let currentEnvName = getJSEnvironment().name;
        return isReactNative()
            &&
            (
                currentEnvName == EnvirType.WINDOWS ||
                currentEnvName == EnvirType.MACINTOSH ||
                currentEnvName == EnvirType.LINUX
            )
    }
    /**
     * 是否关闭远程debugger
     */
    export function isCloseRemoveDebugger(){
        return isReactNative() && getJSEnvironment().name == EnvirType.REACTNATIVE;
    }
    /**
     * @return {name:EnvirType,versionStr:""}
     */
    export function getJSEnvironment() {
        if (navigator.userAgent) {
            var userAgent = navigator.userAgent;
            var platform, result;
            function getDesktopOS() {
                var pf = navigator.platform;
                if (pf.indexOf("Win") != -1) { // 说明当前是Windows操作系统
                    var rVersion = /Windows NT (\d+).(\d)/i;
                    var uaResult = userAgent.match(rVersion);
                    var sVersionStr = "";
                    if (uaResult[1] == "6") {
                        if (uaResult[2] == 1) {
                            sVersionStr = "7"; // 说明当前运行在Windows 7 中
                        } else if (uaResult[2] > 1) {
                            sVersionStr = "8"; // 说明当前运行在Windows 8 中
                        }
                    } else {
                        sVersionStr = uaResult[1];
                    }
                    return { "name": EnvirType.WINDOWS, "versionStr": sVersionStr };
                } else if (pf.indexOf("Mac") != -1) {
                    return { "name": EnvirType.MACINTOSH, "versionStr": "" }; // Macintosh操作系统
                } else if (pf.indexOf("Linux") != -1) {
                    return { "name": EnvirType.LINUX, "versionStr": "" }; // 说明当前运行在Linux操作系统
                }
                return null;
            }
            platform = /Windows Phone (?:OS )?([\d.]*)/; // windows phone的正则表达式
            result = userAgent.match(platform);
            if (result) {
                return ({ "name": EnvirType.WINDOWS_PHONE, "versionStr": result[1] });
            }
            // BlackBerry 10
            if (userAgent.indexOf("(BB10;") > 0) {
                platform = /\sVersion\/([\d.]+)\s/; // BlackBerry的regular expression
                result = userAgent.match(platform);
                if (result) {
                    return { "name": EnvirType.BLACKBERRY, "versionStr": result[1] };
                } else {
                    return { "name": EnvirType.BLACKBERRY, "versionStr": '10' };
                }
            }
            // iOS, Android, BlackBerry 6.0+:
            platform = /\(([a-zA-Z ]+);\s(?:[U]?[;]?)([\D]+)((?:[\d._]*))(?:.*[\)][^\d]*)([\d.]*)\s/;
            result = userAgent.match(platform);
            if (result) {
                var appleDevices = /iPhone|iPad|iPod/;
                var bbDevices = /PlayBook|BlackBerry/;
                if (result[0].match(appleDevices)) {
                    result[3] = result[3].replace(/_/g, ".");
                    return ({ "name": EnvirType.IOS, "versionStr": result[3] }); // iOS操作系统
                } else if (result[2].match(/Android/)) {
                    result[2] = result[2].replace(/\s/g, "");
                    return ({ "name": EnvirType.ANDROID, "versionStr": result[3] }); // Android操作系统
                } else if (result[0].match(bbDevices)) {
                    return ({ "name": EnvirType.BLACKBERRY, "versionStr": result[4] }); // Blackberry
                }
            }
            //Android平台上的Firefox浏览器
            platform = /\((Android)[\s]?([\d][.\d]*)?;.*Firefox\/[\d][.\d]*/;
            result = userAgent.match(platform);
            if (result) {
                return ({ "name": EnvirType.ANDROID, "versionStr": result.length == 3 ? result[2] : "" });
            }
            // Desktop
            return getDesktopOS();
        } else {
            return { "name": EnvirType.REACTNATIVE, "versionStr": "" }
        }
    
    }
    
  • 总结

    • 了解react-native运行过程

    • 解决一些困惑问题

      • 在开发过程中,会遇到开发的功能是完整可行的。打包给测试人员就会发现存在问题(两者JS代码运行环境不同导致的问题)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值