本质上语言和语言的互相调用需要一些条件:
同属一个体系的语言(比如机器语言,或底层为c语言),这样可以通过底层语言实现上层语言之间的通讯。
或者遵循统一的规范,比如 Socket,RPC( 远程过程调用),管道,Web Services 等,把自己的调用请求转换成标准规范(协议或者编码格式),对方按照标准来解析运行。
或者语言与语言之间自己定义标准,比如ExternalInterface(Flash 和 JavaScript 的交互接口 ),缺点是只局限这语言两者。
React Native/Weex实现中满足以下两个条件
1、本地语言有一个脚本的解析引擎。
2、有一个脚本语言到本地语言的映射表,key是脚本语言认识的符号,value是本地语言认识的符号。通过这个映射表来构建从脚本到本地的调用。
而React Native/Weex实现原理差不多,底层都会把js转换为原生API。
比如ReactNative和Android的通信,ReactNative会在一开始通知Java端会把所有要暴漏的Java类的信息封装成Config传给JS,然后根据Config生成对应Java类的Javascript镜像对象,以及要暴露的方法,在JS中调用这个镜像对象的方法就会被转发到对应的Java对象上。而执行ReactNative中的JavaScript需要一个js解析引擎。
而ReactNative和oc的通信则是,在一开始生成OC模块表,然后把这个模块表传入JS中,JS参照模块表,就能间接调用OC的代码。
但开发方式有所不同,Weex 是打包好原生APP,做好配置,引入weexsdk(提供js解析引擎),这个引擎Weex 在 IOS下选择了 JavaScriptCore 内核(RN也是IOS的JavaScriptCore),而在 Android 下选择了 UC 提供的 v8 内核(RN android 是自己实现的JavaScriptCore,这也是为什么安卓项目引入RN包大小会增大4~5M的原因 ), Weex 会把一个页面的源代码全部编译打包成一个 JS bundle。在浏览器中,需要把这个 JS bundle 作为一段 <script> 载入网页,而在客户端里,需要把这段 JS bundle 载入本地,并通过 WeexSDK 直接执行。JS bundle可以部署到云端,用于热更新加载。
ReactNative官方只能将ReactNative基础js库和业务js一起打成一个JS bundle(打包的时候会把index.android.bundle.js或index.ios.bundle.js打包进app,启动app时加载),没有提供分包的功能,需要制作分包打包工具。Weex 默认打的JS bundle只包含业务js代码,体积小很多,基础js库包含在weexsdk中。