CN116974620A - 应用程序的生成方法、运行方法以及相应的装置 - Google Patents

应用程序的生成方法、运行方法以及相应的装置 Download PDF

Info

Publication number
CN116974620A
CN116974620A CN202211457303.7A CN202211457303A CN116974620A CN 116974620 A CN116974620 A CN 116974620A CN 202211457303 A CN202211457303 A CN 202211457303A CN 116974620 A CN116974620 A CN 116974620A
Authority
CN
China
Prior art keywords
component
style
framework
uniapp
data
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CN202211457303.7A
Other languages
English (en)
Inventor
陈肇龙
徐凯鹏
许清华
张梁
梁宇轩
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Tencent Technology Shenzhen Co Ltd
Original Assignee
Tencent Technology Shenzhen Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Tencent Technology Shenzhen Co Ltd filed Critical Tencent Technology Shenzhen Co Ltd
Priority to CN202211457303.7A priority Critical patent/CN116974620A/zh
Publication of CN116974620A publication Critical patent/CN116974620A/zh
Pending legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/70Software maintenance or management
    • G06F8/71Version control; Configuration management
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y02TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
    • Y02DCLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
    • Y02D10/00Energy efficient computing, e.g. low power processors, power management or thermal management

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Computer Security & Cryptography (AREA)
  • Stored Programmes (AREA)

Abstract

本公开实施例提供了一种应用程序的生成方法、运行方法以及相应的装置,属于计算机技术领域。该生成方法包括:获取基于uniapp框架的目标应用程序的程序源代码;对所述程序源代码进行编译,得到适用于app平台的所述目标应用程序的目标代码文件,以基于所述目标代码文件生成适用于app平台的所述目标应用程序的程序包;其中,在编译过程中,若所述程序源代码对应的源样式数据中存在hippy框架不支持的待转换样式数据,根据所述待转换样式数据的样式类型,对所述待转换样式数据进行样式转换,得到hippy框架支持的样式数据,以基于转换后的样式数据进行编译。基于本公开实施例提供的方案,能够有效提供研发效率,更好的满足研发需求。

Description

应用程序的生成方法、运行方法以及相应的装置
技术领域
本公开涉及计算机技术、研发工具的开发等技术领域,具体而言,本公开涉及一种应用程序的生成方法、运行方法以及相应的装置。
背景技术
随着科学技术的飞速发展、人们生活水平的提高,各式各样的应用程序已经成为人们生活中不可或缺的一部分。为了更好的满足应用需求,研发人员也在不断的研发或更新能够为使用者提供更优质服务的应用程序。由于电子设备种类的多样性以及多样性的需求,对于同一个应用程序,研发者经常需求针对不同的程序运行平台(如网页平台、小程序平台、原生应用程序app平台)开发不同的版本。
目前的开源框架中,虽然有些框架也能够实现程序代码的多端复用,实现一套代码可以在两端或者三端上复用,但是目前支持多端复用的框架中,对于app端应用程序的实现并不理想,有的框架会对app端应用程序的落地和后续的开发及维护造成不可以预估的风险和埋坑,有的框架则是对研发人员的代码编写规范有很大的约束。因此,如何改善目前程序研发过程中存在的问题中的一个或多个,仍是本领域技术人员一直在研究的重要问题之一。
发明内容
本公开实施例的目的旨在提供一种能够更好的满足实际应用需求的应用程序的生成方法、应用程序的运行方法以及相应的装置。为了实现上述目的,本公开实施例提供的技术方案如下:
一方面,本公开实施例提供了一种应用程序的生成方法,该方法包括:
获取基于uniapp框架的目标应用程序的程序源代码;
对所述程序源代码进行编译,得到适用于app平台的所述目标应用程序的目标代码文件,以基于所述目标代码文件生成适用于app平台的所述目标应用程序的程序包;
其中,在编译过程中,所述方法包括:
获取所述程序源代码对应的源样式数据;若所述源样式数据中存在hippy框架不支持的待转换样式数据,根据所述待转换样式数据的样式类型,对所述待转换样式数据进行样式转换,得到hippy框架支持的样式数据,以基于转换后的样式数据进行编译。
另一方面,本公开实施例提供了一种应用程序的生成装置,该装置包括:
待编译代码获取模块,用于获取基于uniapp框架的目标应用程序的程序源代码;
代码编译模块,用于对所述程序源代码进行编译,得到适用于app平台的所述目标应用程序的目标代码文件,以基于所述目标代码文件生成适用于app平台的所述目标应用程序的程序包;
其中,在编译过程中,所述代码编译模块用于:获取所述程序源代码对应的源样式数据;若所述源样式数据中存在hippy框架不支持的待转换样式数据,根据所述待转换样式数据的样式类型,对所述待转换样式数据进行样式转换,得到hippy框架支持的样式数据,以基于转换后的样式数据进行编译。
可选的,所述待转换样式数据包括第一样式数据、第二样式数据或第三样式数据中的至少一项;其中,所述待转换样式数据是代码编译模块通过以下方式确定的:
若所述源样式数据中包含第一指定图片格式的源格式图片,将所述源格式图片确定为第一样式数据;
获取第一黑名单,将所述源样式数据中包含在所述第一黑名单中的样式数据,确定为第二样式数据;其中,所述第一黑名单中包含所述uniapp框架支持且所述hippy框架不支持的样式缩写格式和样式值格式;
确定所述源样式数据中的组件数据,所述组件数据包括所述目标应用程序对应的各组件的组件名称和组件样式数据;获取第二黑名单,若所述各组件的组件名称中存在包含在所述第二黑名单中的组件名称,则将包含在所述第二黑名单中的组件名称对应的组件样式数据,确定为第三样式数据;其中,所述第二黑名单中包含至少一个组件名称,所述第二黑名单中的组件名称对应的组件样式类名为至少两个组件的组件样式类名。
可选的,所述代码编译模块可以用于:
对于所述第一样式数据,基于所述程序源代码,得到所述源格式图片对应的抽象语法树,根据该抽象语法树,获取所述源格式图片的图片参数值;基于所述图片参数值,将所述源格式图片转换为第二指定图片格式的目标格式图片;
对于所述第二样式数据,确定所述第二样式数据中的每一样式数据的样式类名,对于每一样式数据,根据该样式数据的样式类名和第一映射关系,确定该样式数据的样式转换策略,并根据该样式转换策略对该样式数据进行转换,得到转换后的样式数据;其中,所述第一映射关系包括至少一种样式类名与对应的样式转换策略之间的对应关系;
对于所述第三样式数据,在组件名称包含在所述第二黑名单中的每个组件的组件参数中,添加该组件的组件样式类名的隔离父层,将每个组件的组件样式类名和隔离父层作为该组件的新组件样式类名。
可选的,所述代码编译模块可以用于:在编译过程中,获取所述程序源代码中包含的各标签的标签名;根据所述各标签的标签名,确定所述各标签中hippy框架不支持的待转换标签;对于每个所述待转换标签,若该待转换标签属于uniapp框架的内置组件,则将待转换标签转换为基于hippy框架的自定义组件中的标签,其中,所述自定义组件在所述目标应用程序在app平台运行时进行注册,若该待转换标签不属于uniapp框架的内置组件,则将待转换标签替换为hippy框架中与该标签相对应的标签。
可选的,所述代码编译模块可以用于:在编译过程中,获取所述程序源代码中包含的各标签的属性信息;对于任一所述标签,若该标签的属性信息包含指定格式的埋点数据,则根据所述埋点数据为该标签添加对应的目标事件和目标属性,以在该标签被创建时通过触发所述目标事件,在所述目标事件中通过调用所述目标属性获得所述埋点数据对应的要采集的目标数据。
可选的,所述目标事件为布局layout事件,所述目标属性为带有键值的ref属性,所述ref属性作为所述layout事件的调用参数;其中,所述ref属性的键值是根据所述埋点数据生成的唯一标识值。
可选的,所述代码编译模块可以用于:在编译过程中,通过读取所述程序源代码对应的组件文件,得到所述程序源代码对应的各组件的组件名称和组件所在的路径,以在所述目标应用程序在app平台运行时,执行以下操作:
对于每个组件,根据该组件所在的路径获取到该组件的组件内容;
基于各组件的组件名称和组件内容进行组件的自动注册。
可选的,所述代码编译模块可以用于:在编译过程中,对所述程序源代码对应的应用层组件添加组件入口层,以在所述目标应用程序在app平台运行时,通过该组件入口层调用对应的应用层组件;若所述程序源代码中包含具有条件编译的代码,若该代码的编译条件与app平台不匹配,则在编译时过滤该代码。
可选的,所述代码编译模块可以用于:在得到转换后的样式数据之后,将所述程序源代码对应的目标样式文件转换为对应的js(脚本)对象,并将所述js对象打包到所述目标代码文件中;其中,所述目标样式文件包括:所述源样式数据中除所述待转换样式数据之外的样式数据、以及所述待转换样式数据对应的转换后的样式数据。
另一方面,本公开实施例还提供了一种应用程序的运行方法,该方法包括:
响应于针对目标应用程序的程序启动操作,对所述目标应用程序进行初始化,所述目标应用程序的程序包是采用本公开任一可选实施例提供的应用程序的生成方法生成的;
通过所述目标应用程序对应的用户界面UI组件,显示所述目标应用程序的用户界面;其中,所述目标应用程序对应的UI组件包括:视图vue框架中的vue核心代码、hippy框架的UI组件中的app平台代码、以及uniapp框架的UI组件中的uniapp增量代码,所述增量代码是uniapp框架的UI组件中除vue核心代码和web平台代码之外的代码。
另一方面,本公开实施例还提供了一种应用程序的运行装置,该装置包括:
操作获取模块,用于接收针对目标应用程序的程序启动操作,所述目标应用程序的程序包是采用本公开任一可选实施例提供的应用程序的生成方法生成的;
处理模块,用于响应于所述程序启动操作,对所述目标应用程序进行初始化,通过所述目标应用程序的用户界面UI组件,显示所述目标应用程序的用户界面;其中,所述目标应用程序的UI组件包括:视图vue框架中的vue核心代码、hippy框架的UI组件中的app平台代码、以及uniapp框架的UI组件中的uniapp增量代码,所述增量代码是uniapp框架的UI组件中除vue核心代码和web平台代码之外的代码。
可选的,处理模块可以用于:对于目标应用程序的用户界面的待显示内容,若该待显示内容对应的视图元素标识包含在预配置数据库中,则根据该视图元素标识对应的目标处理方式对该待显示内容进行预处理;其中,所述预配置数据库中包括至少一种视图元素标识以及每种视图元素标识对应的处理方式,所述至少一种视图元素标识是uniapp框架支持但hippy框不支持的视图vue语法对应的视图元素标识。
可选的,处理模块可以用于:响应于针对所述目标应用程序的用户界面切换操作,通过所述目标应用程序的路由组件确定所述用户界面切换操作对应的目标界面的访问路径,根据所述访问路径将当前用户界面切换至目标界面;其中,在通过所述路由组件创建路由实例时,在所述路由实例的路由参数中添加uniapp框架特有的路由参数;
其中,所述目标应用程序的路由组件是通过以下方式得到的:
获取hippy框架的前端路由组件;基于uniapp框架的路由规范,对hippy框架的前端路由组件进行修改,得到所述目标应用程序的前端路由组件,所述修改包括:
对hippy框架的前端路由组件中的路由导航方法函数进行修改,其中,修改后的路由导航方法函数可识别uniapp框架下的路由所携带的相关数据;
对hippy框架的前端路由组件中路由接口api进行修改,修改后的路由接口api兼容uniapp框架下路由处理规范。
可选的,处理模块在对所述应用程序进行初始化时可以用于:
对所述目标应用程序的服务插件和视图插件进行注册;其中,所述服务插件的注册包括:
在所述服务插件中注入目标钩子函数,所述目标钩子函数包括uniapp框架所支持的应用级别的钩子函数和页面级别的钩子函数;
重写所述目标应用程序的应用级别的vm实例的创建前钩子函数、以及页面级别的vm实例的创建前钩子函数,以使所述应用级别的钩子函数和所述页面级别的钩子函数可被触发;
所述视图插件的注册包括:在所述视图插件中注入视图转换模块,以根据终端的屏幕尺寸或操作系统类型中的至少一项,通过所述视图转换模块将用户界面中的视图元素的显示格式进行统一转换。
可选的,处理模块可以用于:对所述目标钩子函数进行订阅;在所述目标应用程序的运行过程中,响应于触发所述目标钩子函数事件发生,通过callHook钩子函数触发所述目标钩子函数。
可选的,处理模块在对所述应用程序进行初始化时可以用于:对所述目标应用程序的各组件进行注册,其中,所述各组件包括视图组件、布局组件和对应于app平台的hippy框架的原生组件。
可选的,处理模块在对所述应用程序进行初始化时可以用于:对于uniapp框架支持但hippy框架不支持的全局对象,基于hippy框架规范将所述全局对象转换为hippy框架所支持的全局对象,对转换后的全局对象进行全局注册。
另一方面,本公开实施例还提供了一种电子设备,该电子设备包括存储器和处理器,存储器中存储有计算机程序,处理器执行该计算机程序以实现本公开任一可选实施例中提供的方法。
另一方面,本公开实施例还提供了一种计算机可读存储介质,该存储介质中存储有计算机程序,该计算机程序被处理器执行时实现本公开任一可选实施例中提供的方法。
另一方面,本公开实施例还提供了一种计算机程序产品,该计算机产品包括计算机程序,该计算机程序被处理器执行时实现本公开任一可选实施例中提供的方法。
本公开实施例提供的技术方案带来的有益效果如下:
一方面,本公开实施例提供的应用程序的生成方法,在对基于uniapp框架规范所编写的程序源代码进行编译的过程中,会识别该代码对应的样式数据中hippy框架规范所不支持的样式数据,并基于hippy框架规范不支持的样式数据进行转换处理,从而使得转换处理后的样式数据都能够被hippy框架支持,由于hippy框架是能够实现app平台上安卓和ios操作系统双端复用同一套代码的框架,因此,基于本公开实施例提供的程序生成方法,能够将基于uniapp框架的应用程序的程序源代码自动转换实现为能够适用于app平台的目标代码文件,从而基于该文件生成能够在app平台运行的程序包,提高了app端程序的开发效率,更好的满足了实际应用需求。
附图说明
为了更清楚地说明本公开实施例中的技术方案,下面将对本公开实施例描述中所需要使用的附图作简单地介绍。
图1为本公开实施例提供的一种融合了uniapp和hippy框架的新研发框架的技术架构图;
图2为本公开实施例提供的一种uniapp和hippy框架所支持的样式的对比效果示意图;
图3为本公开实施例提供的一种图片格式转换方式的流程示意图;
图4为本公开实施例提供的一种样式处理方式的原理示意图;;
图5为本公开实施例提供的一种处理前和处理后的样式的对比结果;
图6为本公开实施例提供的一种实现样式隔离的方式的流程示意图;;
图7为本公开实施例提供的标签转换方式的流程示意图;;
图8为本公开一个示例中提供的一种埋点曝光的原理示意图;
图9为本公开实施例提供的一种实现埋点曝光的方式的流程示意图;
图10为本公开实施例提供的一种实现组件自动注入的方式的原理示意图;
图11为本公开实施例提供的一种视图vue源码的示意图;
图12为本公开实施例提供的一种对hippy框架中的vue模块进行改造的原理示意图;
图13为本公开实施例提供的一种vue模块的结构示意图;
图14为本公开实施例提供的一种路由模块的改造方式的示意图;
图15为本公开实施例提供的一种插件注册方式的原理示意图;
图16为本公开实施例提供的几种工具链插件的示意图;
图17为本公开实施例提供的研发框架中的部分组件的结构示意图;
图18为本公开实施例提供的部分组件在应用程序的页面中的分布示意图;
图19为本公开实施例提供的一种钩子函数初始化的原理示意图;
图20为本公开实施例提供的一种实现全局对象注册的原理示意图;
图21为本公开实施例提供的一种应用程序的生成方法的流程示意图;
图22为本公开实施例提供的一种应用程序的在多平台上的用户界面的显示结果示意图;
图23为本公开实施例提供的一种应用程序的生成装置的结构示意图;
图24为本公开实施例提供的一种电子设备的结构示意图。
具体实施方式
下面结合本公开中的附图描述本公开的实施例。应理解,下面结合附图所阐述的实施方式,是用于解释本公开实施例的技术方案的示例性描述,对本公开实施例的技术方案不构成限制。
本技术领域技术人员可以理解,除非特意声明,这里使用的单数形式“一”、“一个”、“所述”和“该”也可包括复数形式。应该进一步理解的是,本公开实施例所使用的术语“包括”以及“包含”是指相应特征可以实现为所呈现的特征、信息、数据、步骤、操作、元件和/或组件,但不排除实现为本技术领域所支持其他特征、信息、数据、步骤、操作、元件、组件和/或它们的组合等。应该理解,当我们称一个元件被“连接”或“耦接”到另一元件时,该一个元件可以直接连接或耦接到另一元件,也可以指该一个元件和另一元件通过中间元件建立连接关系。此外,这里使用的“连接”或“耦接”可以包括无线连接或无线耦接。这里使用的术语“和/或”指示该术语所限定的项目中的至少一个,例如“A和/或B”可以实现为“A”,或者实现为“B”,或者实现为“A和B”。在描述多个(两个或两个以上)项目时,如果没有明确限定多个项目之间的关系,这多个项目之间可以是指多个项目中的一个、多个或者全部,例如,对于“参数A包括A1、A2、A3”的描述,可以实现为参数A包括A1或A2或A3,还可以实现为参数A包括参数A1、A2、A3这三项中的至少两项。
本申请实施例提供了一种应用程序的生成方法、以及基于该方法生成的应用程序的运行方法,该生成方法可以由任意的计算机设备执行,可以是终端设备,也可以是服务器,该应用程序的运行方法可以在app平台的电子设备执行,比如,该电子设备可以是采用安卓(Android)系统的终端或采用ios系统(一种操作系统)的终端。其中,上述服务器可以是独立的物理服务器,也可以是多个物理服务器构成的服务器集群或者分布式系统,还可以是提供云计算服务的云服务器。终端设备(也可以称为用户终端)可以是智能手机、平板电脑、笔记本电脑、台式计算机、智能语音交互设备(例如智能音箱)、可穿戴电子设备(例如智能手表)、车载终端、智能家电(例如智能电视)、AR/VR设备等,但并不局限于此。终端以及服务器可以通过有线或无线通信方式进行直接或间接地连接,本公开在此不做限制。
为了更好的理解本公开实施例提供的方案,下面首先对本公开实施例中的所涉及的一些相关技术或技术用语进行介绍和解释。
Uniapp(uniapp):一种可以实现一套代码在小程序端、h5端和app端三端复用代码的开源前端框架。
Hippy(hippy):一种用于构建用户界面的渐进式框架,可以实现安卓和ios双端复用同一套代码的动态开源框架。
跨端:一套代码通过对应的转换器实现在不同端上运行。
Uni2hippy:本公开实施例提供的一种将uniapp的代码运行在hippy引擎之上,从而实现uniapp代码可以在app双端上渲染的框架。
Uni2hippy运行时引擎:本公开实施例提供的Uni2hippy中的运行时引擎,该引擎在执行uniapp代码之前,通过先执行一套流程让hippy的运行时具备uniapp的特性。
Uni2hippy样式编排:本公开实施例提供的Uni2hippy中的样式转换处理方案,可以通过一系列插件通过有序的处理对hippy上不兼容的uniapp样式,进行降级或者转换处理。
样式隔离:就是兄弟、子孙组件之间的样式需要互不影响,不会被覆盖的情况。
Uni2hippy编译时编排:本公开实施例提供的Uni2hippy中的编译方案,就是uniapp在编译时需要一系列loader对其进行处理并加以改造。
目前在跨端领域上已经涌现了很多开发框架,其中最为让大众熟悉和普遍使用的框架中,目前只有taro和uniapp能实现三端(即小程序平台、h5平台和app平台)统一的能力,其中,taro采用的是类似react语法的DSL语言(domain-specific language,领域特定语言),在app侧主要是将DSL转成react-native框架来实现跨APP端。uniapp采用的是类似vue语法的DSL语言,在app侧主要是将DSL转成wexx框架来实现跨APP端。
其中,taro是在app侧基于react-native语法,对于使用vue为UI(userinterface,用户界面)框架的uinapp来说,几乎不可能将uniapp代码转成react-native语法,因此使用了uniapp的团队在app侧只能使用以vue为UI框架的app跨端框架。而uniapp在app侧是将DSL转换成weex框架,但weex这个框架已经在早几年前处于没人维护、放弃的状态,以至于存在很多问题没法修复,如果使用则会对app的落地和后续的开发和维护造成了不可预估的风险和埋坑。
对于目前现有开发框架中存在的问题,本公开实施例提供了一种新的开发框架,以及基于该开发框架实现的应用程序生成方法以及运行方法。本公开实施例提供的该开发框架,可以基于uniapp实现跨端跨框架的多端方法,基于该开发框架,开发者编写一套代码,即可发布到web端、app(APP)端和小程序等多个平台。相比于目前已有的开发框架,本公开实施例提供的方案能够解决以下技术难题中的至少一项:
1.解决了APP端中unaipp无法用weex以外的框架渲染页面内容的难题;
2.解决了uniapp的三端效率问题,让使用uniapp的团队真正做到三端统一;
3.使得hippy能够兼容更多uniapp的样式和写法,扩大了hippy的使用便捷;
4.解决了hippy的埋点曝光问题,使得三端都可以使用统一的声明式埋点写法;
5.解决了uniapp在hippy上的调试问题,让调试更便捷。
本公开实施例提供的开发框架可以称为Uni2hippy(Uni2hippy框架),Uni2hippy实现了前端跨端框架uniapp和动态框架hippy两者的相结合,并优化了uniapp和hippy,可选的,通过在hippy-vue上融合uniapp的运行时特性,从而实现了uniapp跨三端的可行性,让unaipp变成一个真正实用的、能跨三端的前端框架,并扩大了hippy的使用边界。可选的,Uni2hippy通过样式编排中各种操作,从而磨平了uniapp和hippy在样式上的互斥性,通过编译时编排,实现了uniapp上各种标签都可以在hippy-vue引擎上识别和运行。
为了更好的理解和说明本公开实施例提供的方案,下面首先对本公开实施例所提供的Uni2hippy框架进行说明。
图1示出了本公开实施例提供的一种开发框架的结构的示意图,如图1所示,Uni2hippy开发框架可以包括运行时引擎、样式解释编排和编译时编排这几个部分,其中,通过样式解释编排和编译时编排部分可以实现基于uniapp框架的程序源代码(开发者使用uniapp框架编写的程序代码)的编译,在编译过程中,通过样式解释编排和编译时编排,可以对uniapp框架和hippy框架不兼容的样式进行转换或降级处理,对hippy上不支持的标签进行转换或替换处理,从而磨平了uniapp和hippy在样式和标签处理上的互斥性,使得hippy上能够兼容uniapp的样式,通过编译时编排,还可以在编译过程中将uniapp的一些优势融入到Uni2hippy中,实现进一步的优化。运行时引擎是在hippy引擎的基础上进一步优化后的引擎,能够使hippy引擎在运行时具有uniapp的特性,更好的保障了uniapp代码在app端上的正常渲染。
下面对运行时引擎、样式编排和编译时编排这几个部分分别进行说明。
1.样式编排
因为h5(web页面)的样式写法(编写web端代码时可以使用的样式写法),一放到hippy侧就会报错、渲染不出来或者直接crash(崩溃),这是因为在hippy侧采用的是传统的yoga布局引擎(一个基于Flexbox(弹性盒子)的跨平台布局引擎),它识别样式的能力比不上h5渲染引擎丰富。
为了便于理解,图2为本公开实施例提供的一种h5所支持的样式(uniapp支持的样式)和hippy所支持的样式的对比结果示意图,其中,h5支持的样式如图2中较大的圆(图中省略号代表h5支持的其他未列举出的样式),hippy支持的样式是图2中较小的圆,两个圆形成的圆环就是它们两者之间的样式差异,如果将这些差异强行放在小圆内就会出问题。
从图2中可以看出,小圆内的margin(外边距样式属性)、padding(内边距样式属性)、position(定位属性,用于设置对html元素的定位方式)以及background-color(背景颜色样式)等是h5和hippy都支持的样式,而anmation(动画)的常用样式、cale(用来指定元素的长度或者宽度)样式、百分比(百分比样式属性)以及keyframe(在动画序列中定义关键帧的样式)等样式hippy并不支持。
针对uniapp和hippy所支持的样式差异,本公开实施例提供了一种解决方案,该方案可以基于uniapp的框架规范和hippy的框架规范,对uniapp支持但hippy不支持的一些样式(待转换样式数据)进行转换处理,使得hippy能够支持转换后的样式,扩展了hippy所兼容的样式。本公开实施例提供的Uni2hippy通过在编译时或者运行时将这些差异的样式尽可能的用hippy支持的样式降级兼容,样式降级兼容的处理可以包括svg(Scalable VectorGraphics,可缩放的矢量图形)图标(也可称为svg图片)处理、样式自动拆解补全、组件样式隔离等其中的一项或多项。下面对这各项分别进行介绍。
1.1.svg图标处理
该部分用于实现图片格式的转换,可以将uniapp支持但hippy不支持的图片格式的图片(源格式图片)转换为hippy支持的图片格式的图片(标格式图片)。
对于hippy框架的视图层hippy-vue中的background-image(背景图片),hippy-vue虽然可以解析png、jpg等类型的图片,但对于一些特殊格式的图片是不支持的,比如svg格式,因此需要对svg格式的图片进行处理,可以在编译时转换成hippy可支持的格式的图片。为了实现该转换,本公开实施例中,考虑到background-image是可以识别base64png格式(采用base64编码方式的png格式)的图片,因此,可以在webpack(用于现代JavaScript(js)应用程序的静态模块打包工具)和postcss(使用js插件来转换样式的工具)的协助下,可以实现背景图片格式的转换。以hippy不支持的svg格式的图片为例,如图3所示,将该格式的图片转换为hippy支持的图片格式的图片的流程可以包括以下步骤:
步骤1:先将background-image的图片(图3中的svg格式的背景图片)变成ast(Abstract Syntax Tree,抽象语法树);
步骤2:借助postcss-loader(postcss加载器,通过webpack会把样式文件的内容即上述ast传送给postcss-loader),将ast传到postcss-plugin(postcss插件,postcss-plugin是注册到postcss配置中的插件)之中;
步骤3:通过postcss-plugin对ast进行解码处理(即decode),提取得到图片的宽(width)高(height)等数值即图片参数的参数值;
步骤4:基于提取得到的图片参数值,借助第三方的npm包(Node PackageManager,包管理工具)将svg图片转成png图片,然后再用base64格式的形式转换,将base64格式转成base64的png格式返回,得到png格式的图片,即图3中的background-image:base64png。
1.2样式自动拆解补全
在uniapp和hippy的样式差异中,有一部分的差异集中在样式缩写或者样式的值不符合hippy格式的情况,比如,对于边距样式属性的格式缩写和格式值的写法,uniapp和hippy是不同的。针对样式缩写格式、样式值格式所存在的差异问题,本公开实施例中提出可以采取样式拆解、样式补全、样式值处理等方式解决这些样式差异,从而将uniapp支持但hippy不支持的样式缩写和样式值,转化为hippy支持的样式写法和样式值写法。如图4所示,该解决方式的处理流程可以包括以下步骤:
步骤1:先得到样式(转换前的样式,图4中的样式(前))的ast,然后传入到插件中。
具体的,可以通过webpack会把ast传送给postcss-loader,借助postcss-loader将ast传到postcss插件之中,由postcss插件进行进一步处理;
步骤2:样式过滤,将不需要处理的样式(图中样式过滤判断为否的样式)直接返回,需要处理的样式进入下一步。
具体的,该步骤中样式过滤可以基于预配置好的样式黑名单,其中,该黑名单中中包含uniapp框架支持且所述hippy框架不支持的样式缩写格式和样式值格式(如margin,padding,shadow-box等样式的缩写格式及样式值的写法),包含在黑名单中的样式是需要进一步处理的样式,即需要转换的样式。
步骤3:样式类型匹配,每种类型都会有配套的处理函数,从而可以得到专属的处理过程。
步骤4:对于包含在黑名单中的样式,采用该样式的类型所对应的处理函数对该样式的缩写和/或样式值的写法进行处理,得到转换后的样式处理结果(图4中样式(后))后直接返回。
在实际实施时,由于uniapp和hippy中存在格式缩写、格式值写法差异的样式是有多种类型的样式的,每种类型转换方式很有可能是不同的,针对该问题,本公开实施例中,可以预配置不同类型的样式所对应的样式缩写和/或样式值写法的样式转换策略(即配置样式类型和转换策略的映射关系,如图4中所示的样式映射(style mapping),如果应用程序的某个样式包含在黑名单中,则可以根据该样式的样式类型所对应的样式转换策略进行相应的转换处理,得到hippy能够支持的样式。
如图4中所示,黑名单中的样式类型可以包括padding类型、margin类型、带单位的样式类型等等,每种样式对应各自的处理函数(也就是样式转换策略),如padding类型对应的处理函数表示为了padding-handle。作为一个示例,图5示出了一种margin类型的样式转换前后的对比示意图,如图5所示,uniapp框架中margin的样式写法(处理前的格式)是margin,样式值是值(10)和单位(px)的组合,转换后样式写法(处理后的格式)是对转换前的样式进行了样式拆解补全,将“margin”拆解补全为了“margin_left(左外边距)”“margin_right(右外边距)”“margin_top(上外边距)”和“margin_bottom(下外边距)”,并去掉了样式值中的单位。
通过本公开提供的上述样式转换,可以将uniapp和hippy存在写法差异的格式转换为hippy支持的格式。
1.3.样式隔离
因为在目前的hippy-vue中是没有样式隔离的概念,在应用程序运行时,如果电子设备的内存中存在A和B两个组件,而A和B都存在同一个样式名,此时前者的样式会影响到后者,使得样式出现错乱现象。为了解决该问题,本公开实施例提供的解决方式如图6所示,该方式可以基于预配置的组件黑名单列表实现,其中,组件黑名单列表包括的是一些需要进行样式隔离的组件的标识(如组件名称),如图6中示意性示出的组件1(component1)、组件2和组件3,这些组件的样式名与其他至少一个组件的样式名相同,如图6所示,该方式可以包括如下步骤:
步骤1:获取各组件的组件名称(componentName);
作为一个示例,图6中示出了一个组件的书写格式,如下所示,其中,div class=“a”表示组件的样式类型的名称,这个名称会绑定一些样式,p表示组件的名称。
componentName
<div class=″a″>
<p>xxx</p>
<div/>
步骤2:对于任一组件,判断该组件的组件名称是否是在黑名单中,如果不在则不需要对该组件进行处理,如果该组件的组件名称在黑名单中,则需要对该组件进行处理。
具体的,对于组件名称在黑名单中的组件,需要对该组件的组件样式名(样式类名)添加隔离父层,以将该组件和与该组件具有相同样式名的其他组件进行隔离,避免这些组件相互间造成的影响。
如图6所示的示例中,对于上述组件名称为p,组件的样式类名为a的组件,为其组件样式类名所添加的隔离父层为“componentName-Scoped”。
步骤3:对添加了隔离父层的组件进行样式提取,提取该组件的组件类名(提取组件样式数组classlist),其中,该组件的组件类名包括该组件的原样式类名和新添加的隔离父层(在classlist中添加隔离父层类名,即进行了隔离层封装的组件的classlist中包括原样式类名和新添加的隔离父层的样式类名)。
其中,图6中的“样式提取”部分的“是否在黑名单内”的判断和“隔离层封装”部分的“是否在黑名单内”的判断是相同的,在实际实施时,“样式提取”部分的“是否在黑名单内”的判断步骤也可以不实施。如图6中所示的组件名称为p的组件,其最终的样式类名包括原样式类名a和隔离父层的样式类名componentName-Scoped。
通过上述处理,可以实现具有相同样式类名的组件之间的隔离,避免在具有相同样式类名的组件被同时加载到内存中时,一个组件的样式会对存在相同样式类名的另一个组件的样式造成影响,出现样式混乱的情况。
2.编译时编排
uniapp的代码如果要实现在hippy-vue的引擎下执行和渲染,除了在运行时和样式这两块下功夫外,编译时也需要配合多种不同功能的loader(加载器)进行转换,以更好的保证编译后的代码能够在hippy-vue引擎下的正常运行。针对该方面,本公开实施例提供了以下几种重要的loader:
2.1.uni2hippy-template-loader(模板加载器)
因为uniapp中有很多标签都是uniapp才有的,而hippy-vue中提供的标签种类不多,所以该loader的作用是对template中的部分标签进行转换和处理,使得转换后的标签能够被hippy框架所支持。图7示出了该loader的工作原理示意图,如图7所示,通过该loader实现标签转换的流程可以包括以下步骤:
步骤1:该loader根据解析的ast得到tagName。
该步骤可以获取所有视图文件(.vue文件)中的模板(template)中的内容,包括程序代码对应的所有标签数据,可以基于程序代码的所有视图文件得到对应的抽象语法树ast,通过解析程序代码的抽象语法树ast来得到程序代码所对应的所有标签的标签名称。
步骤2:判断标签是否是uniapp所拥有的标签,如果是则进入步骤3,否则进入步骤4。
步骤3:对于任一标签,如果该标签的tagName属于uniapp内置的组件(例如view),则需要将标签转换成为<hippy-view>即hippy能够支持的标签,与此同时需要在js运行时注入自定义组件hippy-view,并且该组件的具体实现只能用hippy支持的基本组件来实现,以使得自定义的组件能够在hippy引擎上正常工作。
如图7所示的示例(eg:<swiper>),swiper组件是uniapp专用的轮播图组件,hippy不支持,如果一个标签是该组件中的标签,那么该标签是uniapp专用的标签,需要将该标签转换为hippy的标签,例如,将该标签替换为hippy_swiper这种形式的自定义组件中的标签,其中,在程序运行时,要进行该自定义组件的注册(即要在runtime中实现并注入名称为“hippy_swiper”的自定义组件),以使得该组件能够被正常使用。
步骤4:判断标签是否属于hippy支持的h5标签,如果是则进入步骤5,否则进入步骤6。
步骤5:如果一个标签的tagName不属于uniapp的内置组件,但是属于hippy支持的h5标签,则不做变化(例如<p>标签(段落标签)),由于该标签是hippy支持的且不属于uniapp的内置组件,因此,该组件可以在程序运行时被hippy引擎正常渲染,可以无需进行转换。
步骤6:如果一个标签的tagName不属于uniapp的内置组件,也不属于hippy支持的h5标签,则需要将标签替换成hippy支持的标签,例如将h1标签(标题标签)直接替换成span标签(可用于修饰文字元素)。
基于本公开实施例提供的uni2hippy-template-loader,在对基于uniap的程序代码进行编译时,可以基于程序代码得到对应的抽象语法树ast,通过解析ast可以得到其中包含的标签的标签名tagename,根据tagename可以判断标签是否需要转换,如果根据tagename确定标签是hippy支持的标签,则不需要进行转化,如果标签不属于hippy支持的标签(包括属于Uniapp内置的组件的标签、以及既不属于uniapp的内置组件,也不属于hippy支持的标签),则需要转化为hippy支持的标签。通过上述处理,可以将应用程序中所涉及的标签都处理为例hippy支持的标签,能够被hippy引擎正常渲染。
2.2.uni2hippy-brow-loader
由于目前的hippy自身是没有关于埋点曝光的能力暴露出来的,只能通过其他方式曝光,考虑到该问题,本公开实施例提供的Uni2hippy框架中提供了一种简洁高效的声明式埋点曝光能力,基于该方案,开发者只要在标签上按照特定的方式种下埋点数据,就可以实现该埋点自动曝光并暴露给业务层进行上报,实现更加简便,可以更好的满足开发者的实际应用需求。
下面示出了本公开实施例提供的一种采用声明式埋点方式在标签上种下埋点数据的一种可选的书写规范:
<tag data-stat=xxx>
xxxx
</tag>
其中,data-stat(也可以采用data-brow或其他特定标识)是一种埋点标识(埋点曝光标识),data-stat=xxx中的“xxx”为data-stat的值,“xxxx”表示标签的其他属性数据,如果一个标签的标签数据中带有该埋点标识,说明该标签需要进行埋点曝光(标签从显示区域/可视区域中不可见到可见区域内时触发)的标签,埋点标识的值(data-stat的值,也就是标签埋点曝光的值)表征了该标签是否出现在终端(如手机)的可视区域内,是为了统计使用者是否滑动到该标签,从而可以判断该标签内容是否吸引使用者的注意。
本公开提供的该方案需要在运行时和编译时两者相配合才能发挥功效,其中编译时的主要作用就是识别标签中特定的书写格式(即上述书写规范),如果识别到标签中带有该特定的书写格式,需要给该标签添加特定属性和事件。
本公开实施例中,对程序代码进行编译时,如果识别到标签中带有该特定的书写格式(也就是特定的埋点数据),表明该标签是需要曝光的标签,编译过程中需要在该标签上添加两个新的属性数据,以使得编译后的需要曝光的标签中都带有这两个属性数据,从而在运行时创建该标签时,可以根据这两个属性数据进行所需的目标数据的采集。
本公开实施例中,上述两个新的属性数据可以包括一个目标事件和一个目标属性,其中,目标事件可以一个是layout(布局)事件,目标属性可以是一个ref属性,该layout事件主要是为了让标签在创建时获取需要采集的该标签的相关数据(如获取标签此时距离顶部的高度值),而ref就是获取该相关数据需要利用到该标签的vm实例。
作为一个示例,图8示出了一种实现标签曝光上报的原理示意图,如图8所示,可以包括以下步骤:
步骤1:计算出需要曝光标签的绝对高度top,并保存下来;
如图8的示例中,标签1(图中的①)的绝对高度(距离页面内容顶部的高度)是top1,标签2(图中的②)的绝对高度是top2,应用程序的用户界面的可视区域的高度为图中所示的高度(Height),图中比较长的矩形框表示应用程序的页面内容。程序的使用者可以通过界面滚动或滑动操作改变可视区域显示的页面内容。
步骤2:每次滚动都可以得到一个offset偏移量;
在图8所示的示例中,每次获取到针对用户界面的上下滚动操作时,都会一个offset偏移量,即一次滚动所引起的页面内容的滚动高度。
step3:当元素的top在[offset,Height+offset]区间内,就认为标签曝光,此时进行曝光上报,否则就不曝光。
如图8所示的示例中,在t1时刻,偏移值offset为0,标签2的高度top2在[0,Height+0]区间,标签2曝光,需要进行上报,标签1未曝光,进行了一次滚动之后,在t2时刻偏移值offset为偏移1,标签1仍未曝光,如果再次滚动,在t3时刻偏移值offset为偏移2,标签1的高度top1在[偏移2,Height+偏移2]区间,标签1曝光,此时标签2进入不可视区域,如果再次滚动,在t4时刻偏移值offset为偏移3,标签1也处于不可视区域。
对于图8所示的场景示例中的埋点曝光需求,需要在标签创建时获取标签此时距离顶部的高度值,那么就需要调用该标签对应的用于获取该高度值的视图实例(vm实例)。该示例中,layout事件主要是为了让标签在创建时获取标签此时距离顶部的高度值,而ref就是获取这个高度需要利用到该标签的vm实例。
图9中示出了本公开实施例提供的一种埋点曝光的实现方式的流程示意图,如图9所示,该方式可以包括图9中的webpack主流程和uni2hippy-brow-loader的处理流程,具体如下:
步骤1:可以利用webpack工具获取到程序代码对应的各视图组件(vue组件),通过解析vue组件可以获取到程序代码对应的各标签的属性数据;
步骤2:基于各标签的属性数据,利用uni2hippy-brow-loader(图9中的brow-hippy-loader)对各标签进行处理,具体包括:
步骤2.1:对于每个标签,确定该标签的属性数据中是否包含特定的埋点数据(如是否包含data-stat(也可写成stat-data)或者是data-brow(也可写成stat-brow)),如果不包含,则无需对该标签进行进一步处理,可以直接返回,如果包含则进入下一步。
步骤2.2:确定该标签的ref属性是否具有值(ref值),如果包含,则直接添加带有该值的ref属性,如果不含有ref值,则根据埋点数据中埋点标识的值生成与该值对应的唯一ref值(具体的生成方式可以根据预配置),并在标签的属性数据中添加带有该唯一ref值的ref属性,并添加该ref属性对应的layout事件,得到处理后的标签并返回。
如图9所示,在经过brow-hippy-loader处理后,可以再通过一些其他loader进行判断是否需要对处理后的标签进行其他处理,其他loader将在后面进行介绍。
作为一个示例,下面示出了一个需要曝光的标签在编译前和标签后的属性数据的对比结果。
由上述对比结果可以看出,在需要对一个标签进行埋点曝光时,编译前,可以在其属性数据中添加特定的埋点数据,即该示例中的data-stat=xxx,在编译过程中,如果识别到标签的属性数据中包含该埋点数据,uni2hippy-brow-loader可以根据data-stat的值衍生出唯一的ref值,即示例中的键值key,ref属性的作用就是可以获取该标签的一个引用。在程序运行时,如果一个标签具有layout事件,标签创建的时候会触发layout事件,然后在layout事件中调用ref,基于ref的key可以确定出获取需要采集并上报的该标签的相关数据(如图8中标签的高度等数据)所要利用的该标签的vm实例,通过执行该vm实例可以获取到需要的相关数据。
2.3.uni2hippy-auto-inject-loader(自动注入加载器)
因为uniapp中所有的业务组件都是通过一个loader在编译时自动注入到js运行时中,从而实现组件自动注入,业务代码不会手动注入到业务层;但hippy是没有这一能力,为了对齐三端,本公开实施例提供的Uni2hippy在编译时提供了一个类似的loader,可称为uni2hippy-auto-inject-loader,专门用来自动注入业务层组件,以避免需要手动注入业务代码的问题。图10示出了本公开实施例提供的通过uni2hippy-auto-inject-loader实现业务代码自动注入的原理示意图,如图10所示,该原理如下:
在开发的时候会将需要的组件都登记在components.json文件(组件文件)上,基于此,本公开实施例提供的实现业务代码自动注入的方案,在编译的时候,该loader会先读取components.json里面的内容(加载components.json),然后获取各组件对应的组件名,根据每个组件名可以获取组件所在的路径,从而在运行时,可以根据各组件所在的路径,解析获取到各个组件的组件内容,通过Vue.component全局注册各个组件,将该loader的编译结果(组件编译后的一段代码字符串)输出到bundle文件里面,一旦运行bundle文件,就会自动将这些组件注入全局,业务层就不用手动注入了。
2.4.其他loader
除了以上几个loader外,本公开实施例还提供了如下的一些其他loader。
uni2hippy-wrapper-loader(包裹加载器):该loader作为辅助loader,主要是用来给一些标签包裹多一层父元素。
在编译特定的某些标签时会使用到这个loader,作用是为了补全应用的入口层,因为开发者开发的unniapp组件都是应用层组件,入口层的骨架类组件是埋藏在uniapp源码中并在uniapp编译时通过通过加载器裹上一层,参考该实现原理,本公开实施例提供的uni2hippy也实现了入口层的骨架类组件,通过warpper-loader添加入口层将应用层组件包裹起来,从而可以通过所添加的入口层实现对这些组件的调用。
uni2hippy-preprocess-loader(预处理加载器):该loader也作为辅助loader,主要是用在条件编译,针对三端一些不能复用只能在各端独自使用的逻辑,可以加上标注从而在编译时进行过滤。在编译过程中,uni2hippy-preprocess-loader可以对程序代码中存在具有条件编译的代码进行判断,如果带有条件编译的代码是需要过滤的(不适用于目标平台的代码,如有的代码标注了是web平台的代码,但要生成的是适用于app平台的编译后的文件),则不需要编译该代码。
uni2hippy-css-modify-loader(样式修改加载器):该loader主要是用来解析uniapp上的样式文件,将css文件上的样式换成js语言上的js对象,可以先执行完样式编排处理,然后将编排后的结果输入到该loader中,最后通过该loader输出一个js对象(编译结果)插入到bundle文件中。
基于本公开实施例提供的Uni2hippy,开发团队可以使用uniapp编写程序代码,通过该框架提供的上述样式编排和编译时编排处理,可以将编写好的程序源代码编译为适用于app平台的目标代码文件(bundle文件),从而可以基于该目标代码文件得到适用于app平台的程序包(如适用于安卓系统的APK或适用于ios的程序包)。通过该Uni2hippy真正实现了编写一套代码,即可得到适用于web平台、小程序平台以及app平台的应用程序的需求。
在根据编译得到的bundle文件生成了适用于app平台的应用程序之后,为了保证该程序在终端设备上的正常运行时,本公开实施例提供的Uni2hippy框架中的运行时引擎是基于hippy引擎实现的,并对hippy引擎进行了优化和改进,下面对本公开实施例提供的运行时引擎进行介绍。
3.运行时引擎
运行时引擎的优化改造包括下述的vue源码改造、.vue-router源码改造和hippy运行时改造这几个部分。
3.1.vue源码改造
uniapp和hippy都是基于vue源码的应用框架,图11示出了vue源码的结构示意图,从图11可以看出,vue是有两种平台类型的版本,一种是基于web的版本,另一种是基于app的weex版本,其中,uniapp采用的是web版本(包含vue源码中的browser(浏览器)部分)编译出来的产物,然后对其进行了源码级别的改造,而hippy的vue部分则是直接采用了vue的core部分(核心代码),所以hippy-vue没有browser部分的代码。
由于小程序端、h5端和app端这三端存在较多的差异性,而vue源码中的web版本的vue只是针对h5端的,所以如果要实现三端统一就必须要增强vue,使得它能暴露出更多的底层能力给到业务层,从而业务层可以尽量的磨平三端差异,因此uniapp是针对vue源码做出了修改的。其中,uniapp对vue源码的修改主要包括以下两点:
①vue从底层向外层暴露出一个_call_hook钩子函数(call_hook的作用就是执行自定义的钩子函数,并将钩子中this指向指为当前组件实例),call_hook可以作为一个应用接口api,该api的目的就是给外层提供一个可以触发vm(Vue对象)实例钩子的能力,从而可以磨平三端的钩子差异。
②在创建vm实例的时候,注入了一些uniapp的信息,目的是为了让uniapp可以磨平三端下api的差异性。
对于hippy而言,因为hippy是一个跨平台的app应用框架,所以不具备传统浏览器的dom(文档对象模型)这类的操作,因此hippy只采用了vue的core部分(v-dom的操作),而浏览器能力部分,则是采用了hippy提供的能力补上,因此出现了以vue-core为底层核心的hippy-vue,给vue添加了原生渲染能力以及原生能力的调用,这些原生渲染能力和原生能力可以统称为hippy原生能力。可见,hippy框架中的vue组件/模块(hppy_vue)可以分解为vue源码中的核心代码(vue的core部分)和hippy原生能力(图12中的hippy特性)两大部分。
如上述所说,hippy-vue采用的是vue的core部分,而uniapp是采用了web版本的vue,所以不能以uniapp修改后的vue源码来兼容hippy-vue,而是在hippy-vue的基础上兼容uniapp对vue的修改,使得修改后的vue能够兼容hippy-vue、以及uniapp_vue中除针对web平台的代码部分之外的修改部分。图12示出了本公开实施例提供的Uni2hippy中的vue模块(uni2hippy-vue,可称为UI组件)的结构示意图,如图12所示,uniapp-vue可以分解为vue核心代码部分(vue-core)、web browser特性部分(vue源码中针对web平台的代码部分)、以及除vue核心代码部分和web浏览器部分之外的增量代码(图12中的uniapp修改),因为uniapp-vue和hippy-vue存在相同部分即vue-core,而uniapp-vue中web browser特性的作用其实和hippy-vue特性的作用一样,就是用来驱动最后的渲染和获取自带的能力,只有uniapp修改是uniapp-vue特有而hippy-vue没有的,考虑到这些因素,本公开实施例提供的方案中,先将hippy特性替换掉web browser特性,而uniapp修改部分保留,并将包含vue-core和hippy特性的hippy-vue和uniapp对vue的修改放到hippy-vue上,即将hippy-vue和uniapp修改部分(图1中的uniapp-vue的能力增强)融合,就可以得到一个可以用具有uniapp特性的hippy-vue,即本公开实施例提供的uni2hippy-vue。
为了避免运行中出现显示异常等问题,本公开实施例中对经过上述改造处理后得到的uni2hippy-vue进行了进一步的优化处理,具体如下:对于以h5的代码来编译的程序代码,其中会存在很多在hippy中不规范的语法,即hippy不能够识别的语法,如果直接使用经过上述改造后的uni2hippy-vue,这些不规范的语法可能会导致用户界面的显示出现问题。为了解决这些问题,本公开实施例提供的方案可以将这些不规范的语法在运行时进行处理,以达到不修改业务层又能被hippy识别的效果。在上述经过改造后的uni2hippy-vue的基础上,本公开实施例还提供了以下处理方式:
1.钩子兼容处理
因为uniapp修改主要是为了在业务层能触发自定义的钩子,而这能力添加到hippy上会存在个别排斥现象,如onPageScroll钩子函数(用于获取视图元素位置信息的钩子函数),主要原因是在uniapp的修改有一小部分是在web browser特性部分上修改,而这部分修改是没法放在hippy-vue上,所以只能丢弃,但丢弃后就会出现这些个别的钩子在触发的时候匹配不到vm实例,针对该问题,本公开实施例中,通过在_call_hook函数上加上hippy兼容处理,可以让uniapp上的所有钩子都可以在hippy上触发。
也就是说,在程序的运行过程中,可以通过_call_hook函数对hippy不支持即排斥的钩子函数进行订阅,如果订阅到触发这些钩子函数的事件,可以通过_call_hook函数触发这些钩子函数,以使得uniapp的钩子函数都能够在新框架上触发。
可选的,hippy不支持的钩子函数主要是与web browser特性部分关联的钩子函数、以及uniapp独有的一些钩子,如uniapp所支持的页面级别的钩子函数和应用级别的钩子函数中的至少一项。
2.平台端鲁棒性增强处理:
因为基于uniapp实现的项目中存在的很多不符合hippy规范的语法,对于不规范的语法的一部分语法,本公开实施例提供的uni2hippy-vue提供了相应的解决方式,具体的,在应用程序的运行过程中,如果当前的用户界面中要显示的内容中存在不符合hippy规范的语法的内容,可以通过公将不符合规范的内容过滤掉,或者是通过添加父元素等方式进行处理,使得处理后的内容能够被hippy支持,从而可以正常显示。
可选的,可以预配置一数据库(或语法列表),该数据库中可以包括至少一种视图元素标识以及每种视图元素标识对应的处理方式,这里的至少一种视图元素标识中的各标识是uniapp框架支持但hippy框不支持的视图(vue)语法对应的视图元素标识,,该数据库中可以包括hippy不支持但uniapp支持的vue语法中的至少部分语法所对应的视图元素标识。基于该数据库可以实现运行时vue的增强处理,处理流程包括:确定用户界面中的待显示内容对应的视图元素标识是否包含该数据库中,如果是,则根据该数据库进一步确定该待显示内容对应的处理方式,采用该方式对该内容进行相应的预处理。
可选的,上述数据库中的视图元素标识可以包括但不限于div标签的标识(div在h5端支持纯文本,但是app端不支持)、vh单位(uniapp中支持的样式单位,但ios系统的app平台不支持)的标识、纯文本格式的标识等。其中,div标签对应的处理方式可以是过滤掉对应的纯文本,vh单位对应的处理方式可以是将vh单位修改成hippy规范支持的样式单位,避免因为vh单位造成crash问题,如果需要显示的内容是纯文本,可以对纯文本添加父元素格式(即为纯文本添加一层hippy格式所支持的样式)。
经过上述图12中所示的vue改造和上述钩子兼容处理、平台端鲁棒性增强处理后的uni2hippy-vue的结构示意图如图13所示,其中的vue-core和hippy特征也就是hippy-vue,uniapp修改、钩子兼容和平台端鲁棒性增强这三部分则是新的优化内容(对应于图1中的uniapp-vue的能力增强),在hippy-vue的基础上实现了uniapp的一些能力的扩充和完善。
3.2.vue源码改造vue-router源码改造(vue路由组件/模块的改造)
对于vue框架中的路由组件(简称为vue-router)部分,uniapp和hippy都对vue-router做了修改,为了能够提高Uni2hippy的兼容能力,本公开实施例中,以hippy修改过后的vue-router(hippy-vue-router)为模板,通过添加部分的uniapp对于vue-router的修改,使得修改后的hippy-vue-router中具备了uniapp的路由跳转信息。
为了实现目前hippy-vue-router上对于uniapp的修改的兼容,本公开实施例提供的方案中,对hippy-vue-router进行了如下改造:
①在hippy-vue-router中对router.push添加uniapp的修改,主要是为了能识别uniapp路由携带的附加数据。
其中,router.push是一个方法,该方法可以定义导航链接,通该方法的参数可以是一个字符串路径或者一个描述地址的对象,使用router.push方法,可以实现路径跳转,想要导航到不同的url(统一资源定位符)地址,需要使用该方法。通过对router.push添加uniapp中与该方法的功能对应的修改(即在hippy-vue-router的router.push方法的参数中增加uniapp中实现路由跳转的方法中所携带的相关数据),可以使得修改后的hippy-vue-router既可以识别hippy路由携带的路由数据,也可以识别uniapp路由携带的附加数据。
②在hippy-vue-router的路由创建时添加uniapp特有的路由数据(路由信息),该修改是为了模拟uniapp的路由跳转。
在运行时进行路由创建时,hippy和uniapp创建的路由实例中携带的参数(即路由数据)是有所不同的,有些参数是uniapp特有而hippy不具有的,为了使得修改后的hippy-vue-router能够模拟uniapp的路由跳转,需要将uniapp特有的参数在路由创建时添加进去。其中,可以根据uniapp和hippy路由创建时所携带的路由参数的差异,预设定具体需要添加哪些路由数据。
③在hippy-vue-router的路由api中兼容uniapp对路由特有的处理。
该部分与上述第②部分类似,uniapp的路由api中有一些路由处理方式时uniapp特有的,为了让修改后的hippy-vue-router能够兼容uniapp的这些能力,可以在hippy-vue-router的路由api中添加uniapp特有的路由处理方式。
通过上述改造后的hippy-vue-router兼备了uniapp的部分路由跳转能力,考虑到uniapp和hippy在某些特性的处理上会存在差异甚至互斥,本公开实施例还提供了进一步的优化方案,通过对上述改造后的hippy-vue-router进行对冲式兼容处理,解决uniapp和hippy在路由处理方面的差异或互斥。其中,本公开实施例提供的对冲式兼容具体如下:
①去除web特有的api对象,如location等,取而代之的是采用hippy提供的History对象代替。
②hippy只支持history模式,基于hippy规范,用hippy支持的方式实现history的pushState事件(用于存储当前历史记录点);
③uniapp对路由添加的路由信息需要过滤性添加到hippy的路由对象上,也就是说,对于uniapp特有的路由信息,在路由创建时添加这些特有信息时,如果这些特有信息中的某些信息是hippy规范不支持的,则不添加或者是采用hippy规范对不支持的特有路由信息进行替换后再添加。可选的,预先配置相应的黑名单,该黑名单中可以包括uniapp特有但不能添加到路由中的路由信息,或者预配置白名单,只将包含在白名单中的路由信息添加到hippy的路由中。
通过上述改进后的hippy-vue-router即为本公开实施例提供的路由组件,即图1中所示的uni2hippy-vue-router,其具备目标hippy-vue-router的能力,以及改造后的uniapp-vue-router的部分能力(图1中所示的uniapp-vue-router的能力增强)。图14中示出了基于hippy-vue-router和uniapp-vue-router得到本公开实施例的该uni2hippy-vue-router的原理示意图,如图14所示,uniapp-vue-router可以分解为vue框架中的vue-router代码部分(图14中的vue-router)和uniapp对vue框架的vue-router所做的修改部分(uniapp的修改),hippy-vue-router可以分解为vue-router代码部分和hippy对vue框架的vue-router所做的修改部分,通过在hippy-vue-router的基础上,增加了uniapp的修改中的部分修改以及上述对冲式兼容的处理,得到了uni2hippy-vue-router。
3.3.hippy运行时改造
该部分包括插件注册、组件注册、声明钩子初始化、以及global(全局)挂载api和特定对象等部分的改造处理,其中,插件注册、组件注册、声明钩子初始化、以及global(全局)挂载api和特定对象等操作是需要在程序启动时的初始化阶段执行的,以保证应用程序对应的组件、插件和api等都能够被正常调用,触发钩子函数的事件发生时,钩子函数可被触发。下面对这几个部分分别进行介绍。
3.3.1.插件注册(即图1中的plugin注册)
本公开实施例提供的uni2hippy的运行时机制中,存在两个很重要的插件,一个逻辑层相关的插件即service plugin(服务插件),另一个是视图层相关的插件即viewplugin(视图插件),这两种插件主要是用来对齐uniapp的视图层(负责处理事件合成)和逻辑层(负责触发钩子和应用实例化)。本公开实施例的uni2hippy运行时机制中还提供了其他插件的注册,包括一些工具类的插件,以更好的满足开发者的需求。
①service plugin注册,在程序的初始化阶段进行service plugin的注册时通过在该插件中初始化所有需要的钩子函数,以使hippy具备uniapp的逻辑层的功能。因为hippy-vue是以vue为主,所以只具备uniapp的组件级别的钩子,而uniapp中的钩子函数包括组件级别的钩子、应用级别的钩子以及页面层级的钩子,而为了让hippy也具备uniapp的应用级别的钩子和页面层级的钩子的两种钩子,所以需要在service插件中初始化所有需要的钩子,以及针对某些钩子进行定制逻辑。
如图15中所示,本公开实施例中,在程序的运行初始化阶段进行service plugin的注册时,可以通过以下流程实现钩子函数的初始化:
a1:在hippy中注入uniapp特有的钩子函数,包括上述uniapp所具备的应用级别的各钩子函数和页面级别的钩子函数。
a2:在创建路由实例时,需要重写vm实例的beforecreate钩子(创建前钩子函数),以实现应用级别的钩子函数和页面级别的钩子都可以被触发。
其中,可以通过步骤a21重写应用级别vm实例的beforecreate钩子,实现应用级别的钩子函数可以被触发,通过步骤a22中的重写页面级别的vm实例的beforecreate钩子实现页面级别的钩子函数可以被触发。
a21:重写应用级别vm实例的beforecreate钩子
首先,需要将创建好的路由实例注入到vm实例的$router(全局的路由实例,是router构造方法的实例,在Vue实例内部,可以通过$router访问路由实例)中,即图15中的vm注入路由实例的步骤,这样做的目的就是为了将路由跳转的权限收归到uniapp提供的路由api上(如uni.navigator(uniapp中页面跳转组件))等,而不是每个组件都可以进行路由跳转;然后可以初始化路由导航,如beforeEach(全局前置导航钩子),afterEach(全局后置钩子函数)等,之后将globalState(全局状态)注入到vm实例中,通过上述处理,实现了应用级别的钩子函数的全局注入,从而在能够触发这些钩子函数对应的触发事项发生时,这些钩子函数就可以被触发。如在程序初始化时,就会触发一些应用级别的钩子函数,如onLaunch,onShow等应用生命周期函数。
a22:重写页面级别的vm实例的beforecreate钩子
对于页面级别的vm实例,为了实现应用级别的钩子函数可被触发,需要在页面级别的vm实例中注入一系列uniapp的路由参数和其他自定义的数据(其他特定参数,如_page_等页面属性),同时也触发一系列页面级别的钩子如onLoad钩子(订阅页面加载)等。
由于路由实例(即vue-router的实例)和vm实例(即vue实例)都有各自对应的钩子函数,在应用程序启动运行时,路由实例和vm实例都需要在初始化阶段进行创建,在实例创建时,对于应用级别的钩子函数而言,通过重写应用级别的vm实例,将创建好的路由实例注入到vm实例的$router中并初始化路由导航,可以实现应用级别的钩子的注入,从而可以在满足对应的触发条件时能够被触发,而页面级别的钩子函数是与应用程序的页面相关联的,因此,对于该级别的钩子函数,通过在vm实例中注入钩子函数所关联的页面的路由参数等数据,即可实现在满足钩子函数对应的触发条件时钩子函数能够被触发。
②view plugin注册
视图层插件主要的作用就是为了应对与视图相关的能力提供,如安卓和ios系统识别rpx单位(小程序端的尺寸单位)换算能力,以及统一两端(android和ios系统)字体大小集合的能力等。
在实际应用中,运行应用程序的终端设备的显示屏的屏幕尺寸是多样化的,其中,使用android和ios这两种操作系统的终端设备的尺寸是可能存在差异的,即便是使用同一种操作系统的终端设备的屏幕尺寸也存在多样化,对于app端的应用程序,对于用户界面上的视图元素,为了使得具有不同屏幕尺寸的终端设备能够具有统一格式的显示效果,本公开实施例的视图插件中提供了视图转换模块,该模块可以根据终端设备的屏幕尺寸自适应对视图元素(如字体)的显示效果进行转换。其中,该视图转换模块可以包括字体转换模块(功能模块)和/或响应单位转换模块,该字体转换模块可以将用户界面上的字体的大小进行转换,响应单位转换模块可以实现视图元素的尺寸单位的转换,比如,将小程序端的尺寸单位转换为app端支持的尺寸单位。
通过注册带有上述视图转换模块的视图插件,可以解决app端的应用程序的用户界面中视图元素的显示格式不统一的问题。
③tool-chain plugins(工具链插件)注册:
service plugin和view plugin这两类插件都是服务于业务层,而因为app开发不像h5开发那样方便,所以还需要提供对应的开发调试工具链。为了更好的满足开发人员的需求,本公开实施例提供的Uni2hippy框架中还提供了一些工具链插件,如图16所示,包括以下几个插件:
uni2hippy-console插件(调试插件):专门针对uni2hippy研发的一个类似vconsole的前端日志工具,目的就是让开发者通过手机就可以查看hippy的日志。
uni2hippy-gateway插件(网关插件):该插件可以让开发者在不同的环境下进行开发和调试,如通过gateway本地可以连接不同机器的服务,或者蓝盾包连接预发环境的接口等。
uni2hippy-sentry插件(异常检测插件):通过该插件可以便于线上定位问题和查看异常位置的代码。
3.3.2.组件注册
因为Uni2hippy除了包含已经hippy化的uniapp组件(经过处理后使得hippy能够支持的uniapp组件)外,还需要包含一些原生封装好的组件(hippy框架中的原生组件)。
对于hippy化的uniapp组件,又可分为视图组件和布局组件,布局组件主要的作用就是构成页面的骨架,如路由组件,弹层组件,tabbar(底部导航栏)组件等,这些组件是不会暴露给业务层使用;而视图组件,如cover-image.vue等这类组件是提供给业务层调用的组件。图17中示出了本公开实施例提供的Uni2hippy框架中的uni2hippy组件(图1中uni2hippy组件库部分的hippy化的uni组件)的示意图,其中示出的部分布局组件包括:APP.vue(是主组件,所有页面都是在App.vue下进行切换的,是页面入口文件)、Layout.vue(布局组件)、Router-view.vue(路由组件)、Page.vue(分页组件)、Body.vue(内容组件)等,图中示出的部分视图组件包括Radio.vue(单项选择器组件)、Video.vue(视频组件)、cover-view.vue(可覆盖在原生组件上的文本组件)、cover-image.vue(可覆盖在原生组件上的图片组件)和input.vue(输入框组件)等。
除了上述hippy化的uniapp组件,本公开实施例提供的uni2hippy组件还包括hippy框架的原生组件(图1中所示的原生能力的hippy组件),原生组件就是存在一些组件是必须由原生提供然后前端调用的组件,这些组件需要额外引入到uni2hippy的运行时中,从而更好的保证了app端应用程序的正常运行。
uni2hippy组件库中的组件在应用程序在app端运行时的用户界面上对应的页面示意图如图18所示,从图18中可以看出,布局组件构成了页面的骨架,hippy化的业务组件、hippy原生组件以及一些自定义组件(如编译过程中通过template-loader进行标签转换处理时的自定义组件,如hippy-view组件)是提供给业务层调用的组件。
3.3.3.生命钩子初始化
因为uniapp中存在很多小程序平台才有的钩子函数,如onPullDownRefresh(订阅针对页面的下拉动作,一般用于下拉刷新),onPageScroll(订阅页面滚动),onReachBottom(页面滚动到底部的事件,常用于下拉下一页数据)等钩子函数,这些钩子函数的触发是和用户的操作或者uniapp的API脱不了关系,为了弥补hippy的这一缺陷,本公开实施例提供了相应的解决方案,如图19所示,该解决方案包括如下步骤:
步骤1:首先在运行时开始的时候,通过Vue提供的$on函数(在vue中,“$on”函数用于订阅当前实例上的自定义事件)将这些特殊的钩子(hippy中不具有的钩子,包括前文中描述的页面层级的钩子函数和应用级别的钩子函数)进行订阅(即通过Vue.$on订阅各种钩子);
步骤2:然后业务层(视图层)会对步骤1中被订阅的钩子函数注册到vm(vue对象)上,可选的,通过Vue注册钩子或者uni-composition-api(该api允许灵活地组合组件逻辑)提供的钩子在vm上进行注册;
步骤3:最后当视图层通过用户触发或者通过调用uniapp提供的api触发,就会触发到之前订阅的钩子(即如果用户或者api触发了触发某个被订阅的钩子函数的事件,该钩子函数会被触发),如图19中所示,可以通过vm.$emit钩子(该钩子函数用于触发当前实例上的事件)触发,如果触发的是页面级别的钩子函数,可以调用callPageHook钩子触发vm上之前注册的该页面级别的钩子函数,如果触发的是应用级别的钩子函数,可以调用callAppHook钩子触发vm上之前注册的该页面级别钩子函数,即图19中的触发订阅函数。
3.3.4.Global挂载uni API和特定对象:
uniapp是集合了h5端和小程序端的特性的,如h5环境下的window对象(表示一个浏览器窗口或一个框架),document对象(代表整个文档)等全局对象,小程序上存在wx这个全局对象(wx对象,是小程序自带的对象),uniapp还存在一个uni这个全局对象(uni对象),因此,uniapp中是存在多种全局对象的。而hippy由于是原生渲染,所以不可能存在h5和小程序的全局对象和uniapp特有的uni对象和uni特性api,因此为了要实现三端统一,必须在用hippy的方式直接或者间接实现这些对象,从而实现三端一致,如图20所示,对于uniapp中存在但hippy中不存在的uni对象、wx对象、getAPP(可以用于获取全局的实例)、widows对象等全局对象,首先需要采用hippy方式实现或者替换这些全局对象,即基于用hippy框架规范,将这些uniapp中存在但hippy中不存在全局对象进行转换或替换处理,得到hippy框架规范支持的具有相应功能的全局对象,之后通过将这些转换后的这些对象挂载到global上(将这些全局对象挂载到全局对象上相当于实现了对象的全局注册),即可实现业务层对于这些全局对象的调用。
如图1所示的本公开实施例提供的Uni2hippy框架,该框架中还可以包括polyfill(polyfill是一个js库,主要抚平不同浏览器之间对js实现的差异)或其他一些通用的能够抚平环境差异的功能结构。
基于本公开实施例提供的Uni2hippy框架,可以实现三端复用同一套代码,可以大大提升应用程序的开发效率和开发复用率,缩短开发时长。目前的uniapp由于weex已经被放弃,uniapp在app侧无法做到跨端,而Uni2hippy弥补了uniapp在app端的缺失,且拓展了hippy框架的影响范围,为hippy框架让更多使用uniapp的团队所使用,推动hippy的发展,更好的满足了开发者的实际使用需求。
基于本公开实施例提供的Uni2hippy框架,本公开实施例提供了一种应用程序的生成方法、以及一种应用程序的运行方法,下面通过对几个示例性实施方式的描述,对本公开提供的上述应用程序的生成方法和运行方法可选实施例以及本公开的技术方案产生的技术效果进行说明。需要指出的是,下述实施方式之间可以相互参考、借鉴或结合,对于不同实施方式中相同的术语、相似的特征以及相似的实施步骤等,不再重复描述。
图21示出了本公开实施例提供的一种应用程序的生成方法,该方法可以任意电子设备执行,该设备中可以部署有本公开实施例提供的Uni2hippy框架,可选的,可以至少部署有该框架中的样式编排和编译时编排部分的结构,如图21所示,该方法可以包括如下步骤:
步骤S110:获取基于uniapp框架的目标应用程序的程序源代码;
步骤S120:对所述程序源代码进行编译,得到适用于app平台的目标应用程序的目标代码文件;
步骤S130:基于上述目标代码文件生成适用于app平台的该目标应用程序的程序包。
其中,在编译过程中,该方法包括:获取程序源代码对应的源样式数据如CSS(Cascading Style Sheets,层叠样式表)文件;若源样式数据中存在hippy框架不支持的待转换样式数据,根据待转换样式数据的样式类型,对待转换样式数据进行样式转换,得到hippy框架支持的样式数据,以基于转换后的样式数据进行编译。
本公开实施例中,目标应用程序可以是能够提供任意服务的任意程序,如提供在线购物服务的应用程序,提供理财服务的应用程序等等。目标应用程序的程序源代码是研发人员使用uniapp框架编写的该程序的程序代码(也就是用户代码),可选的,该程序源代码可以是对应于web平台的程序代码,也可以是对应于小程序平台的程序。基于本公开提供的应用程序的生成方法,可以在对程序源代码进行编译的过程中,将该程序源代码对应的样式数据(即上述源样式数据)中hippy框架不支持的样式转换为hippy框架支持的样式数据,基于此可以编译得到能够适用于app平台的该目标应用程序的目标代码文件(bundle文件),可选的,在得到目标代码文件之后可以基于该文件生成适用于app平台的该目标应用程序的程序包,如在使用安卓系统或ios操作系统的终端设备上运行的应用程序包。
本公开实施例中,上述待转换样式数据可以包括前文中的样式编排部分所及的hippy框架不支持的图片格式(如svg格式)、样式缩写格式、样式值格式、或者需要样式隔离的组件的样式数据中的至少一项,相应的,上述待转换样式数据的样式类型可以是图片、样式缩写、样式值、组件的样式数据等类型,对于不同的样式类型的待转换样式数据,可以采用相应的转换方式进行样式转换,以得到hippy支持的样式数据。
本公开的可选实施例中,上述待转换样式数据包括第一样式数据、第二样式数据或第三样式数据中的至少一项。
其中,第一样式数据可以是通过以下方式确定的:
若上述源样式数据中包含第一指定图片格式(如svg格式)的源格式图片,将源格式图片确定为第一样式数据,第一指定图片格式为hippy框架不支持的图片格式。
第一样式数据即前文中“svg图标处理”部分所描述的uniapp支持但hippy不支持的图片格式的图片,如svg格式的背景图片,因为hippy不支持该格式的图片,为了使得程序运行时该格式的图片能够被正常渲染,需要转换为hippy框架规范支持的图片格式。
因此,对于第一样式数据,在源程序代码的编译过程中,根据待转换样式数据的样式类型对待转换样式数据进行样式转换,可以包括:
对于第一样式数据,基于程序源代码,得到源格式图片对应的抽象语法树,根据该抽象语法树,获取源格式图片的图片参数值;基于图片参数值,将源格式图片转换为第二指定图片格式的目标格式图片,如将svg格式的图片转换为png格式的图片),可选的,可以采用图3中所示的方式实现图片格式的转换。
本公开的实施例中,第二样式数据可以是通过以下方式确定的:
获取第一黑名单(即样式黑名单),其中,第一黑名单中包含uniapp框架支持且hippy框架不支持的样式缩写格式和样式值格式;
将源样式数据中包含在第一黑名单中的样式数据,确定为第二样式数据。
对于该第二样式数据,根据待转换样式数据的样式类型对待转换样式数据进行样式转换,可以包括:
确定第二样式数据中的每一样式数据的样式类名(样式类名表征了具体的样式类型,如padding类型、margin类型等);
对于第二样式数据中的每一样式数据,根据该样式数据的样式类名和第一映射关系,确定该样式数据的样式转换策略,并根据该样式转换策略对该样式数据进行转换,得到转换后的样式数据;其中,第一映射关系包括至少一种样式类名与对应的样式转换策略之间的对应关系,如图4中所示的style mapping。
本公开的实施例中,上述第三样式数据可以是通过以下方式确定的:
确定源样式数据中的组件数据,组件数据包括目标应用程序对应的各组件的组件名称和组件样式数据;
获取第二黑名单(如图6中的组件黑名单列表),若各组件的组件名称中存在包含在第二黑名单中的组件名称,则将包含在第二黑名单中的组件名称对应的组件样式数据,确定为第三样式数据;其中,第二黑名单中包含至少一个组件名称,第二黑名单中的组件名称对应的组件样式类名为至少两个组件的组件样式类名。
对于第三样式数据,上述根据待转换样式数据的样式类型对待转换样式数据进行样式转换,可以包括:
在组件名称包含在第二黑名单中的每个组件的组件参数中添加该组件的组件样式类名的隔离父层,将每个组件的组件样式类名和隔离父层作为该组件的新组件样式类名。
如图6所示的示例中,为包含在组件黑名单列表中的组件名称为p的组件的样式类名a添加了父样式类名(隔离父层),将类名a和父样式作为该组件的新组件样式类型,实现具有相同样式名的组件之间的隔离,避免相互之间造成影响。
本公开的可选实施例中,该方法还可以包括:
在编译过程中,获取程序源代码中包含的各标签的标签名;
根据各标签的标签名,确定各标签中hippy框架不支持的待转换标签;
若待转换标签属于uniapp框架的内置组件,则将待转换标签转换为基于hippy框架的自定义组件中的标签,其中,该自定义组件在目标应用程序在app平台运行时需要进行注册;
若待转换标签不属于uniapp框架的内置组件,则将待转换标签替换为hippy框架中与该标签相对应的标签。
该方案可以通过编译时编排部分的uni2hippy-template-loader实现,其中,具体实现流程可以采用图7中所示的方案。通过该可选方案,可以将uniapp中有但hippy-vue中不支持的标签转换为能够被hippy框架规范支持的标签。
本公开的可选实施例中,该方法还可以包括:
在编译过程中,获取程序源代码中包含的各标签的属性信息;
对于任一标签,若该标签的属性信息包含指定格式的埋点数据,则根据埋点数据为该标签添加对应的目标事件和目标属性,以在该标签被创建时通过触发所述目标事件,在目标事件中通过调用所述目标属性获得所述埋点数据对应的要采集的目标数据。
其中,该可选方案可以通过Uni2hippy框架中的uni2hippy-brow-loader实现,如图9中所示的实现原理。可选的,上述目标事件为布局layout事件,上述目标属性为带有键值的ref属性,ref属性作为layout事件的调用参数;其中,ref属性的键值是根据埋点数据生成的唯一标识值。
本申请实施例中,上述指定格式的埋点数据可以包括特定(指定)指定的埋点标识(如前文中的data-stat)和该特定的埋点标识的值,其中,一个标签的该埋点标识的值是指标签是否出现在终端的可视区域内,在一个标签的属性信息中包含指定格式的埋点数据时,通过添加特定的目标事件和目标属性,可以在标签创建时通过获取标签的与显示相关数据,知晓标签是否出现在了可视区域中。
本公开的可选实施例中,该方法还可以包括:
在编译过程中,通过读取程序源代码对应的组件文件,得到程序源代码对应的各组件的组件名称和组件所在的路径,以在目标应用程序在app平台运行时,执行以下操作:
对于每个组件,根据该组件所在的路径获取到该组件的组件内容;
基于各组件的组件名称和组件内容进行组件的自动注册。
通过该可选方案,可以实现业务层组件的自动化注入,无需手动注入。可选的,该方案可以通过uni2hippy-auto-inject-loader实现。
本公开的可选实施例中,在编译过程中,该方法还可以包括:
对程序源代码对应的应用层组件添加组件入口层,以在目标应用程序在app平台运行时,通过该组件入口层调用对应的应用层组件;
若程序源代码中包含具有条件编译的代码,若该代码的编译条件与app平台不匹配,则在编译时过滤该代码。
该方案可以通过uni2hippy-wrapper-loader和uni2hippy-preprocess-loader实现,通过uni2hippy-wrapper-loader为应用层组件添加入口层,实现对应用层组件的调用,通过uni2hippy-preprocess-loader可以实现对不需要编译的代码的过滤。
本公开的可选实施例中,在得到转换后的样式数据之后,该方法还包括:
将程序源代码对应的目标样式文件转换为对应的js对象,并将js对象打包到目标代码文件中;
其中,目标样式文件包括:源样式数据中除待转换样式数据之外的样式数据、以及待转换样式数据对应的转换后的样式数据。
对于该可选方案,可以通过uni2hippy-css-modify-loader实现,该加载器可以将经过样式编排处理后的样式数据进行编译得到编译结果,该编译结果作为目标代码文件的一部分。
基于本公开实施例提供的Uni2hippy框架中的样式编排和编译时编排的代码编译处理,可以将基于uniapp框架规范所编写的程序代码自动编译得到适用于app平台的程序,实现了app端、小程序端和web端这三端统一,开发者编写一套代码,即可得到能够发布到web端、app端(包括)和小程序等多个平台的应用程序包。
本公开实施例提供的方案适用于uniapp跨端应用,开发团队可以同时开发h5、小程序和app三端。作为一个示例,图22中示出了基于本公开实施例提供的方案,实现的一个应用程序的一套代码在app端、h5端以及小程序端上的均能够正常运行的一个应用程序的用户界面的示意图,其中,对于app端而言,可以是基于研发人员编写的程序代码(使用uinapp框架的编写的代码),通过该本公开实施例提供的Uni2hippy转换成hippy规范支持的目标代码文件,从而得到适用于app端的程序包,图中的各种元素(如元素1、元素2、其他元素等)为应用程序的用户界面/页面上的显示内容,图22中所示的用户界面上还显示有多个控件的名称(如控件1)以及控件的图标,程序的使用者可以通过对各个控件进行点击操作触发新的用户界面的显示。
基于本公开实施例提供的Uni2hippy框架,本公开实施例还提供了一种应用程序的运行方法,该方法可由终端设备执行,该终端设备可以是采用安卓系统的终端,也可以是采用ios系统的终端,可选的,该终端设备可以至少部署有Uni2hippy框架中的运行时引擎部分的结构,本公开实施例的该应用程序的运行方法可以包括如下步骤:
响应于针对目标应用程序的程序启动操作,对目标应用程序进行初始化,目标应用程序的程序包是采用本公开实施例提供的应用程序的生成方法生成的;
通过目标应用程序的用户界面UI组件,显示目标应用程序的用户界面;其中,目标应用程序的UI组件包括:视图vue框架中的vue核心代码、hippy框架的UI组件中的app平台代码、以及uniapp框架的UI组件中的uniapp增量代码,该增量代码是uniapp框架的UI组件中除vue核心代码和web平台代码之外的代码。
其中,该方法可以基于图1中所示的运行时引擎部分的结构实现,上述UI组件即为图1中所示的uni2hippy-vue,该vue可以在支持hippy-vue的同时,还兼容uniapp-vue的修改部分所提供的能力,从而可以将通过Uni2hippy对基于uniapp的程序源代码进行编译进而得到目标应用程序,能够被hippy引擎正常渲染出来并展示给程序的使用者。
本公开的可选实施例中,该方法还包括:
对于目标应用程序的用户界面的待显示内容,若该待显示内容对应的视图元素标识包含在预配置数据库中,则根据该视图元素标识对应的目标处理方式对该待显示内容进行预处理;
其中,所述预配置数据库中包括至少一种视图元素标识以及每种视图元素标识对应的处理方式,所述至少一种视图元素标识是uniapp框架支持但hippy框不支持的视图vue语法对应的视图元素标识。
该可选方案对应于前文中的“平台端鲁棒性增强”部分,通过该可选方案,在用户界面的待显示内容的语法不符合hippy规范的语法时,可以通过内容过滤、给内容添加父元素的样式等处理方式对这些内容进行处理,从而可以避免有的内容不能够正常显示或者造成程序运行崩溃等问题。其中,上述视图元素标识可以包括但不限于div标签中的纯文本的标识、纯文本标识、使用安卓和/或ios操作系统的app端不支持的单位等等,不同类型的视图元素标识可以预配置各自对应的处理方式。
本公开的可选实施例中,该方法还包括:
响应于针对目标应用程序的用户界面切换操作,通过目标应用程序的路由组件确定用户界面切换操作对应的目标界面的访问路径,根据访问路径将当前用户界面切换至目标界面;
其中,在通过路由组件创建路由实例时,在路由实例的路由参数中添加uniapp框架特有的路由参数;
其中,目标应用程序的路由组件是通过以下方式得到的:
获取hippy框架的前端路由组件(hippy-vue-router);基于uniapp框架的路由规范,对hippy框架的前端路由组件进行修改,得到目标应用程序的前端路由组件,该修改可以包括:
对hippy框架的前端路由组件中的路由导航方法函数(router.push)进行修改,其中,修改后的路由导航方法函数可识别uniapp框架下的路由所携带的相关数据;
对hippy框架的前端路由组件中路由接口api进行修改,修改后的路由接口api兼容uniapp框架下路由处理规范。
其中,目标应用程序的路由组件对应于图1中的uni2hippy-vue-router部分,通过该路由组件可以更好的保障目标应用程序中用户界面的切换或跳转的实现。
本公开的可选实施例中,上述对应用程序进行初始化,包括:
对目标应用程序的服务插件和视图插件进行注册。
可选的,上述服务插件的注册包括:
在服务插件中注入目标钩子函数,目标钩子函数包括uniapp框架所支持的应用级别的钩子函数和页面级别的钩子函数;
重写目标应用程序的应用级别的vm实例的创建前钩子函数、以及页面级别的vm实例的创建前钩子函数,以使应用级别的钩子函数和页面级别的钩子函数可被触发。
可选的,上述视图插件的注册包括:在视图插件中注入视图转换模块,以根据终端的屏幕尺寸或操作系统类型中的至少一项,通过视图转换模块将用户界面中的视图元素的显示格式进行统一转换。
该方案对应于前文中的组件注册部分的视图组件和服务组件的注册,在初始化阶段对组件进行注册使得组件可以被调用。本公开实施例提供的服务组件在注册时,会将hippy不支持但uniapp所支持的页面级别的钩子函数和应用级别的钩子函数(全局的钩子函数)在服务组件中注入,从而使得这些钩子函数也能够被正常触发,扩充了改造后的hippy框架所具有的能力。
本公开的可选实施例中,该方法还包括:
对目标钩子函数进行订阅;
将目标钩子函数注册到对应的vm实例上;
在目标应用程序的运行过程中,响应于触发目标钩子函数事件发生,通过callHook钩子函数触发目标钩子函数。
该可选方案中,通过将钩子函数注册到与其对应的vm实例上并对这些钩子函数进行订阅,可以使得应用程序的运行过程中能够钩子函数的目标事件发生时,钩函数会被触发执行。如图19所示,应用级别的钩子函数可以注册到应用级别的vm实例上,页面级别的钩子函数被注册到相对应的页面级别的vm实例上。在触发某个钩子函数的目标事件发生时,可以通过相应级别的callHook钩子函数触发该钩子函数。
本公开的可选实施例中,对应用程序进行初始化还包括:
对目标应用程序的各组件进行注册,其中,各组件包括视图组件、布局组件和对应于app平台的hippy框架的原生组件。
其中,目标应用程序的各组件即为目标应用程序所对应的图1中所示的uni2hippy组件库中的各个组件,在初始化阶段进行组件注册,使得组件可以被正常调用。
本公开的可选实施例中,对应用程序进行初始化还包括:
对于uniapp框架支持但hippy框架不支持的全局对象,基于hippy框架规范将全局对象转换为hippy框架所支持的全局对象,对转换后的全局对象进行全局注册。
其中,可以通过将上述的全局对象挂载到目标应用程序对应的global对象上,实现这些全局对象的全局注册,为了保证这些全局对象被hippy支持,在挂载前,可以基于hippy规范对这些全局对象进行转换或替换处理,从而使得这些全局对象可以被业务层调用,实现相应的功能。
基于与本公开实施例提供的应用程序的生成方法相同的原理,本公开实施例还提供了一种应用程序的生成装置,该生成装置中可以部署有本公开实施例提供的Uni2hippy框架,如图23所示,该应用程序的生成装置100可以包括待编译代码获取模块110和代码编译模块120。其中:
待编译代码获取模块110,用于获取基于uniapp框架的目标应用程序的程序源代码;
代码编译模块120,用于对程序源代码进行编译,得到适用于app平台的目标应用程序的目标代码文件,以基于目标代码文件生成适用于app平台的目标应用程序的程序包;
其中,在编译过程中,代码编译模块120用于:获取程序源代码对应的源样式数据;若源样式数据中存在hippy框架不支持的待转换样式数据,根据待转换样式数据的样式类型,对待转换样式数据进行样式转换,得到hippy框架支持的样式数据,以基于转换后的样式数据进行编译。
可选的,待转换样式数据包括第一样式数据、第二样式数据或第三样式数据中的至少一项;其中,所待转换样式数据是代码编译模块通过以下方式确定的:
若源样式数据中包含第一指定图片格式的源格式图片,将源格式图片确定为第一样式数据;
获取第一黑名单,将源样式数据中包含在第一黑名单中的样式数据,确定为第二样式数据;其中,第一黑名单中包含uniapp框架支持且hippy框架不支持的样式缩写格式和样式值格式;
确定源样式数据中的组件数据,组件数据包括目标应用程序对应的各组件的组件名称和组件样式数据;获取第二黑名单,若各组件的组件名称中存在包含在第二黑名单中的组件名称,则将包含在第二黑名单中的组件名称对应的组件样式数据,确定为第三样式数据;其中,第二黑名单中包含至少一个组件名称,第二黑名单中的组件名称对应的组件样式类名为至少两个组件的组件样式类名。
可选的,代码编译模块可以用于:
对于第一样式数据,基于程序源代码,得到源格式图片对应的抽象语法树,根据该抽象语法树,获取源格式图片的图片参数值;基于图片参数值,将源格式图片转换为第二指定图片格式的目标格式图片;
对于第二样式数据,确定第二样式数据中的每一样式数据的样式类名,对于每一样式数据,根据该样式数据的样式类名和第一映射关系,确定该样式数据的样式转换策略,并根据该样式转换策略对该样式数据进行转换,得到转换后的样式数据;其中,第一映射关系包括至少一种样式类名与对应的样式转换策略之间的对应关系;
对于第三样式数据,在组件名称包含在第二黑名单中的每个组件的组件参数中,添加该组件的组件样式类名的隔离父层,将每个组件的组件样式类名和隔离父层作为该组件的新组件样式类名。
可选的,代码编译模块可以用于:在编译过程中,获取程序源代码中包含的各标签的标签名;根据各标签的标签名,确定各标签中hippy框架不支持的待转换标签;对于每个所述待转换标签,若该待转换标签属于uniapp框架的内置组件,则将该待转换标签转换为基于hippy框架的自定义组件中的标签,其中,自定义组件在目标应用程序在app平台运行时进行注册,若该待转换标签不属于uniapp框架的内置组件,则将该待转换标签替换为hippy框架中与该标签相对应的标签。
可选的,代码编译模块可以用于:在编译过程中,获取程序源代码中包含的各标签的属性信息;对于任一标签,若该标签的属性信息包含指定格式的埋点数据,则根据埋点数据为该标签添加对应的目标事件和目标属性,以在该标签被创建时通过触发目标事件,在目标事件中通过调用目标属性获得埋点数据对应的要采集的目标数据。
可选的,目标事件为布局layout事件,目标属性为带有键值的ref属性,ref属性作为layout事件的调用参数;其中,ref属性的键值是根据埋点数据生成的唯一标识值。
可选的,代码编译模块可以用于:在编译过程中,通过读取程序源代码对应的组件文件,得到程序源代码对应的各组件的组件名称和组件所在的路径,以在目标应用程序在app平台运行时,执行以下操作:
对于每个组件,根据该组件所在的路径获取到该组件的组件内容;
基于各组件的组件名称和组件内容进行组件的自动注册。
可选的,代码编译模块可以用于:在编译过程中,对程序源代码对应的应用层组件添加组件入口层,以在目标应用程序在app平台运行时,通过该组件入口层调用对应的应用层组件;若程序源代码中包含具有条件编译的代码,若该代码的编译条件与app平台不匹配,则在编译时过滤该代码。
可选的,代码编译模块可以用于:在得到转换后的样式数据之后,将程序源代码对应的目标样式文件转换为对应的脚本js对象,并将js对象打包到目标代码文件中;其中,目标样式文件包括:源样式数据中除待转换样式数据之外的样式数据、以及待转换样式数据对应的转换后的样式数据。
本公开实施例还提供了一种应用程序的运行装置,该运行装置包括:
操作获取模块,用于接收针对目标应用程序的程序启动操作,该目标应用程序的程序包是采用本公开实施例提供的应用程序的生成方法生成的;
处理模块,用于响应于程序启动操作,对目标应用程序进行初始化,通过目标应用程序的用户界面UI组件,显示目标应用程序的用户界面;其中,目标应用程序的UI组件包括:视图vue框架中的vue核心代码、hippy框架的UI组件中的app平台代码、以及uniapp框架的UI组件中的uniapp增量代码,增量代码是uniapp框架的UI组件中除vue核心代码和web平台代码之外的代码。
可选的,处理模块可以用于:对于目标应用程序的用户界面的待显示内容,若该待显示内容对应的视图元素标识包含在预配置数据库中,则根据该视图元素标识对应的目标处理方式对该待显示内容进行预处理;其中,预配置数据库中包括至少一种视图元素标识以及每种视图元素标识对应的处理方式,至少一种视图元素标识是uniapp框架支持但hippy框不支持的视图vue语法对应的视图元素标识。
可选的,操作获取模块还可以用于:针对目标应用程序的获取用户界面切换操作;
处理模块可以用于:响应于该用户界面切换操作,通过目标应用程序的路由组件确定用户界面切换操作对应的目标界面的访问路径,根据访问路径将当前用户界面切换至目标界面;其中,在通过路由组件创建路由实例时,在路由实例的路由参数中添加uniapp框架特有的路由参数;
其中,目标应用程序的路由组件是通过以下方式得到的:
获取hippy框架的前端路由组件;基于uniapp框架的路由规范,对hippy框架的前端路由组件进行修改,得到目标应用程序的前端路由组件,修改包括:
对hippy框架的前端路由组件中的路由导航方法函数进行修改,其中,修改后的路由导航方法函数可识别uniapp框架下的路由所携带的相关数据;
对hippy框架的前端路由组件中路由接口api进行修改,修改后的路由接口api兼容uniapp框架下路由处理规范。
可选的,处理模块在对应用程序进行初始化时可以用于:
对目标应用程序的服务插件和视图插件进行注册;其中,服务插件的注册包括:
在服务插件中注入目标钩子函数,目标钩子函数包括uniapp框架所支持的应用级别的钩子函数和页面级别的钩子函数;
重写目标应用程序的应用级别的vm实例的创建前钩子函数、以及页面级别的vm实例的创建前钩子函数,以使应用级别的钩子函数和页面级别的钩子函数可被触发;
视图插件的注册包括:在视图插件中注入视图转换模块,以根据终端的屏幕尺寸或操作系统类型中的至少一项,通过视图转换模块将用户界面中的视图元素的显示格式进行统一转换。
可选的,处理模块可以用于:对目标钩子函数进行订阅;在目标应用程序的运行过程中,响应于触发目标钩子函数事件发生,通过callHook钩子函数触发目标钩子函数。
可选的,处理模块在对应用程序进行初始化时可以用于:对目标应用程序的各组件进行注册,其中,各组件包括视图组件、布局组件和对应于app平台的hippy框架的原生组件。
可选的,处理模块在对应用程序进行初始化时可以用于:对于uniapp框架支持但hippy框架不支持的全局对象,基于hippy框架规范将全局对象转换为hippy框架所支持的全局对象,对转换后的全局对象进行全局注册。
本公开实施例的装置可执行本公开实施例所提供的方法,其实现原理相类似,本公开各实施例的装置中的各模块所执行的动作是与本公开各实施例的方法中的步骤相对应的,对于装置的各模块的详细功能描述具体可以参见前文中所示的对应方法中的描述,此处不再赘述。
基于本公开实施例提供的方法,本公开实施例中还提供了一种电子设备,该电子设备包括存储器、处理器及存储在存储器上的计算机程序,该处理器执行存储器中存储的计算机程序时可实现本公开任一可选实施例中的方法。
可选的,图24中示出了本发明实施例所适用的一种电子设备的结构示意图,如图24所示,该电子设备可以为服务器或者用户终端,该电子设备可以用于实施本发明任一实施例中提供的方法。
如图24中所示,该电子设备2000主要可以包括至少一个处理器2001(图24中示出了一个)、存储器2002、通信模块2003和输入/输出接口2004等组件,可选的,各组件之间可以通过总线2005实现连接通信。需要说明的是,图24中示出的该电子设备2000的结构只是示意性的,并不构成对本公开实施例提供的方法所适用的电子设备的限定。
其中,存储器2002可以用于存储操作系统和应用程序等,应用程序可以包括在被处理器2001调用时实现本发明实施例所示方法的计算机程序,还可以包括用于实现其他功能或服务的程序。存储器2002可以是ROM(Read Only Memory,只读存储器)或可存储静态信息和指令的其他类型的静态存储设备,RAM(Random Access Memory,随机存取存储器)或者可存储信息和计算机程序的其他类型的动态存储设备,也可以是EEPROM(ElectricallyErasable Programmable Read Only Memory,电可擦可编程只读存储器)、CD-ROM(CompactDisc Read Only Memory,只读光盘)或其他光盘存储、光碟存储(包括压缩光碟、激光碟、光碟、数字通用光碟、蓝光光碟等)、磁盘存储介质或者其他磁存储设备、或者能够用于携带或存储具有指令或数据结构形式的期望的程序代码并能够由计算机存取的任何其他介质,但不限于此。
处理器2001通过总线2005与存储器2002连接,通过调用存储器2002中所存储的应用程序实现相应的功能。其中,处理器2001可以是CPU(Central Processing Unit,中央处理器),通用处理器,DSP(Digital Signal Processor,数据信号处理器),ASIC(Application Specific Integrated Circuit,专用集成电路),FPGA(FieldProgrammable Gate Array,现场可编程门阵列)或者其他可编程逻辑器件、晶体管逻辑器件、硬件部件或者其任意组合,其可以实现或执行结合本发明公开内容所描述的各种示例性的逻辑方框,模块和电路。处理器2001也可以是实现计算功能的组合,例如包含一个或多个微处理器组合,DSP和微处理器的组合等。
电子设备2000可以通过通信模块2003(可以包括但不限于网络接口等组件)连接到网络,以通过网络与其它设备(如用户终端或服务器等)的通信,实现数据的交互,如向其他设备发送数据或从其他设备接收数据。其中,通信模块2003可以包括有线网络接口和/或无线网络接口等,即通信模块可以包括有线通信模块或无线通信模块中的至少一项。
电子设备2000可以通过输入/输出接口2004可以连接所需要的输入/输出设备,如键盘、显示设备等,电子设备200自身可以具有显示设备,还可以通过接口2004外接其他显示设备。可选的,通过该接口2004还可以连接存储装置,如硬盘等,以可以将电子设备2000中的数据存储到存储装置中,或者读取存储装置中的数据,还可以将存储装置中的数据存储到存储器2002中。可以理解的,输入/输出接口2004可以是有线接口,也可以是无线接口。根据实际应用场景的不同,与输入/输出接口2004连接的设备,可以是电子设备2000的组成部分,也可以是在需要时与电子设备2000连接的外接设备。
用于连接各组件的总线2005可以包括一通路,在上述组件之间传送信息。总线2005可以是PCI(Peripheral Component Interconnect,外设部件互连标准)总线或EISA(Extended Industry Standard Architecture,扩展工业标准结构)总线等。根据功能的不同,总线2005可以分为地址总线、数据总线、控制总线等。
可选的,对于本发明实施例所提供的方案而言,存储器2002可以用于存储执行本发明方案的计算机程序,并由处理器2001来运行,处理器2001运行该计算机程序时实现本发明实施例提供的方法或装置的动作。
基于与本公开实施例提供的方法相同的原理,本公开实施例提供了一种计算机可读存储介质,该计算机可读存储介质上存储有计算机程序,计算机程序被处理器执行时可实现前述方法实施例的相应内容。
本公开实施例还提供了一种计算机程序产品,该产品包括计算机程序,该计算机程序被处理器执行时可实现前述方法实施例的相应内容。
需要说明的是,本公开的说明书和权利要求书及上述附图中的术语“第一”、“第二”、“第三”、“第四”、“1”、“2”等(如果存在)是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的本公开的实施例能够以除图示或文字描述以外的顺序实施。
应该理解的是,虽然本公开实施例的流程图中通过箭头指示各个操作步骤,但是这些步骤的实施顺序并不受限于箭头所指示的顺序。除非本文中有明确的说明,否则在本公开实施例的一些实施场景中,各流程图中的实施步骤可以按照需求以其他的顺序执行。此外,各流程图中的部分或全部步骤基于实际的实施场景,可以包括多个子步骤或者多个阶段。这些子步骤或者阶段中的部分或全部可以在同一时刻被执行,这些子步骤或者阶段中的每个子步骤或者阶段也可以分别在不同的时刻被执行。在执行时刻不同的场景下,这些子步骤或者阶段的执行顺序可以根据需求灵活配置,本公开实施例对此不限制。
以上所述仅是本公开部分实施场景的可选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本公开的方案技术构思的前提下,采用基于本公开技术思想的其他类似实施手段,同样属于本公开实施例的保护范畴。

Claims (20)

1.一种应用程序的生成方法,其特征在于,所述方法包括:
获取基于uniapp框架的目标应用程序的程序源代码;
对所述程序源代码进行编译,得到适用于app平台的所述目标应用程序的目标代码文件,以基于所述目标代码文件生成适用于app平台的所述目标应用程序的程序包;
其中,在编译过程中,所述方法包括:
获取所述程序源代码对应的源样式数据;
若所述源样式数据中存在hippy框架不支持的待转换样式数据,根据所述待转换样式数据的样式类型,对所述待转换样式数据进行样式转换,得到hippy框架支持的样式数据,以基于转换后的样式数据进行编译。
2.根据权利要求1所述的方法,其特征在于,所述待转换样式数据包括第一样式数据、第二样式数据或第三样式数据中的至少一项;
其中,所述待转换样式数据是通过以下方式确定的:
若所述源样式数据中包含第一指定图片格式的源格式图片,将所述源格式图片确定为第一样式数据;
获取第一黑名单,将所述源样式数据中包含在所述第一黑名单中的样式数据,确定为第二样式数据;其中,所述第一黑名单中包含uniapp框架支持且hippy框架不支持的样式缩写格式和样式值格式;
确定所述源样式数据中的组件数据,所述组件数据包括所述目标应用程序对应的各组件的组件名称和组件样式数据;获取第二黑名单,若所述各组件的组件名称中存在包含在所述第二黑名单中的组件名称,则将包含在所述第二黑名单中的组件名称对应的组件样式数据,确定为第三样式数据;其中,所述第二黑名单中包含至少一个组件名称,所述第二黑名单中的组件名称对应的组件样式类名为至少两个组件的组件样式类名。
3.根据权利要求2所述的方法,其特征在于,所述根据所述待转换样式数据的样式类型对所述待转换样式数据进行样式转换,包括:
对于所述第一样式数据,基于所述程序源代码,得到所述源格式图片对应的抽象语法树,根据该抽象语法树,获取所述源格式图片的图片参数值;基于所述图片参数值,将所述源格式图片转换为第二指定图片格式的目标格式图片;
对于所述第二样式数据,确定所述第二样式数据中的每一样式数据的样式类名,对于所述第二样式数据中的每一样式数据,根据该样式数据的样式类名和第一映射关系,确定该样式数据的样式转换策略,并根据该样式转换策略对该样式数据进行转换,得到转换后的样式数据;其中,所述第一映射关系包括至少一种样式类名与对应的样式转换策略之间的对应关系;
对于所述第三样式数据,在组件名称包含在所述第二黑名单中的每个组件的组件参数中,添加该组件的组件样式类名的隔离父层,将每个组件的组件样式类名和隔离父层作为该组件的新组件样式类名。
4.根据权利要求1至3中任一项所述的方法,其特征在于,所述方法还包括:
在编译过程中,获取所述程序源代码中包含的各标签的标签名;
根据所述各标签的标签名,确定所述各标签中hippy框架不支持的待转换标签;
对于每个所述待转换标签,若该待转换标签属于uniapp框架的内置组件,则将该待转换标签转换为基于hippy框架的自定义组件中的标签,其中,所述自定义组件在所述目标应用程序在app平台运行时进行注册;
对于每个所述待转换标签,若该待转换标签不属于uniapp框架的内置组件,则将该待转换标签替换为hippy框架中与该标签相对应的标签。
5.根据权利要求1至3中任一项所述的方法,其特征在于,所述方法还包括:
在编译过程中,获取所述程序源代码中包含的各标签的属性信息;
对于任一所述标签,若该标签的属性信息包含指定格式的埋点数据,则根据所述埋点数据为该标签添加对应的目标事件和目标属性,以在该标签被创建时通过触发所述目标事件,在所述目标事件中通过调用所述目标属性获得所述埋点数据对应的要采集的目标数据。
6.根据权利要求5所述的方法,其特征在于,所述目标事件为布局layout事件,所述目标属性为带有键值的ref属性,所述ref属性作为所述layout事件的调用参数;
其中,所述ref属性的键值是根据所述埋点数据生成的唯一标识值。
7.根据权利要求1至3中任一项所述的方法,其特征在于,所述方法还包括:
在编译过程中,通过读取所述程序源代码对应的组件文件,得到所述程序源代码对应的各组件的组件名称和组件所在的路径,以在所述目标应用程序在app平台运行时,执行以下操作:
对于每个组件,根据该组件所在的路径获取到该组件的组件内容;
基于各组件的组件名称和组件内容进行组件的自动注册。
8.根据权利要求1至3中任一项所述的方法,其特征在于,在编译过程中,所述方法还包括:
对所述程序源代码对应的应用层组件添加组件入口层,以在所述目标应用程序在app平台运行时,通过该组件入口层调用对应的应用层组件;
若所述程序源代码中包含具有条件编译的代码,若该代码的编译条件与app平台不匹配,则在编译时过滤该代码。
9.根据权利要求1至3中任一项所述的方法,其特征在于,在得到转换后的样式数据之后,所述方法还包括:
将所述程序源代码对应的目标样式文件转换为对应的脚本js对象,并将所述js对象打包到所述目标代码文件中;
其中,所述目标样式文件包括:所述源样式数据中除所述待转换样式数据之外的样式数据、以及所述待转换样式数据对应的转换后的样式数据。
10.一种应用程序的运行方法,其特征在于,所述方法包括:
响应于针对目标应用程序的程序启动操作,对所述目标应用程序进行初始化,所述目标应用程序的程序包是采用权利要求1至9中任一项所述的方法生成的;
通过所述目标应用程序对应的用户界面UI组件,显示所述目标应用程序的用户界面;其中,所述目标应用程序对应的UI组件包括:视图vue框架中的vue核心代码、hippy框架的UI组件中的app平台代码、以及uniapp框架的UI组件中的uniapp增量代码,所述增量代码是uniapp框架的UI组件中除vue核心代码和web平台代码之外的代码。
11.根据权利要求10所述的方法,其特征在于,所述方法还包括:
对于所述目标应用程序的用户界面的待显示内容,若该待显示内容对应的视图元素标识包含在预配置数据库中,则根据该视图元素标识对应的目标处理方式对该待显示内容进行预处理;
其中,所述预配置数据库中包括至少一种视图元素标识以及每种视图元素标识对应的处理方式,所述至少一种视图元素标识是uniapp框架支持但hippy框不支持的视图vue语法对应的视图元素标识。
12.根据权利要求10所述的方法,其特征在于,所述方法还包括:
响应于针对所述目标应用程序的用户界面切换操作,通过所述目标应用程序的路由组件确定所述用户界面切换操作对应的目标界面的访问路径,根据所述访问路径将当前用户界面切换至目标界面;
其中,在通过所述路由组件创建路由实例时,在所述路由实例的路由参数中添加uniapp框架特有的路由参数;
其中,所述目标应用程序的路由组件是通过以下方式得到的:
获取hippy框架的前端路由组件;
基于uniapp框架的路由规范,对hippy框架的前端路由组件进行修改,得到所述目标应用程序的前端路由组件,所述修改包括:
对hippy框架的前端路由组件中的路由导航方法函数进行修改,其中,修改后的路由导航方法函数可识别uniapp框架下的路由所携带的相关数据;
对hippy框架的前端路由组件的路由接口api进行修改,其中,修改后的路由api兼容uniapp框架下路由处理规范。
13.根据权利要求10所述的方法,其特征在于,所述对所述应用程序进行初始化,包括:
对所述目标应用程序的服务插件和视图插件进行注册;
其中,所述服务插件的注册包括:
在所述服务插件中注入目标钩子函数,所述目标钩子函数包括uniapp框架所支持的应用级别的钩子函数和页面级别的钩子函数;
重写所述目标应用程序的应用级别的vm实例的创建前钩子函数、以及页面级别的vm实例的创建前钩子函数,以使所述应用级别的钩子函数和所述页面级别的钩子函数可被触发;
所述视图插件的注册包括:在所述视图插件中注入视图转换模块,以根据终端的屏幕尺寸或操作系统类型中的至少一项,通过所述视图转换模块将用户界面中的视图元素的显示格式进行转换。
14.根据权利要求10至13任一项所述的方法,其特征在于,所述方法还包括:
对目标钩子函数进行订阅,所述目标钩子函数包括uniapp框架所支持的应用级别的钩子函数和页面级别的钩子函数;
将所述目标钩子函数注册到相对应的视图实例上;
在所述目标应用程序的运行过程中,响应于触发所述目标钩子函数事件发生,通过callHook钩子函数触发所述目标钩子函数。
15.根据权利要求10至12任一项所述的方法,其特征在于,所述对所述应用程序进行初始化,包括:
对所述目标应用程序的各组件进行注册,其中,所述各组件包括视图组件、布局组件和对应于app平台的hippy框架的原生组件。
16.根据权利要求10至12任一项所述的方法,其特征在于,所述对所述应用程序进行初始化,包括:
对于uniapp框架支持但hippy框架不支持的全局对象,基于hippy框架规范将所述全局对象转换为hippy框架所支持的全局对象,对转换后的全局对象进行全局注册。
17.一种应用程序的生成装置,其特征在于,所述装置包括:
待编译代码获取模块,用于获取基于uniapp框架的目标应用程序的程序源代码;
代码编译模块,用于对所述程序源代码进行编译,得到适用于app平台的所述目标应用程序的目标代码文件,以基于所述目标代码文件生成适用于app平台的所述目标应用程序的程序包;
其中,在编译过程中,所述代码编译模块用于:获取所述程序源代码对应的源样式数据;若所述源样式数据中存在hippy框架不支持的待转换样式数据,根据所述待转换样式数据的样式类型,对所述待转换样式数据进行样式转换,得到hippy框架支持的样式数据,以基于转换后的样式数据进行编译。
18.一种应用程序的运行装置,其特征在于,所述装置包括:
操作获取模块,用于接收针对目标应用程序的程序启动操作,所述目标应用程序的程序包是采用权利要求1至9中任一项所述的方法生成的;
处理模块,用于响应于所述程序启动操作,对所述目标应用程序进行初始化,通过所述目标应用程序的对应的用户界面UI组件,显示所述目标应用程序的用户界面;
其中,所述目标应用程序对应的UI组件包括:视图vue框架中的vue核心代码、hippy框架的UI组件中的app平台代码、以及uniapp框架的UI组件中的uniapp增量代码,所述增量代码是uniapp框架的UI组件中除vue核心代码和web平台代码之外的代码。
19.一种电子设备,其特征在于,所述电子设备包括存储器和处理器,所述存储器中存储有计算机程序,所述处理器执行所述计算机程序以实现权利要求1至16任一项所述的方法。
20.一种计算机可读存储介质,其特征在于,所述存储介质中存储有计算机程序,所述计算机程序被处理器执行时实现权利要求1至16任一项所述的方法。
CN202211457303.7A 2022-11-21 2022-11-21 应用程序的生成方法、运行方法以及相应的装置 Pending CN116974620A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202211457303.7A CN116974620A (zh) 2022-11-21 2022-11-21 应用程序的生成方法、运行方法以及相应的装置

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202211457303.7A CN116974620A (zh) 2022-11-21 2022-11-21 应用程序的生成方法、运行方法以及相应的装置

Publications (1)

Publication Number Publication Date
CN116974620A true CN116974620A (zh) 2023-10-31

Family

ID=88473683

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202211457303.7A Pending CN116974620A (zh) 2022-11-21 2022-11-21 应用程序的生成方法、运行方法以及相应的装置

Country Status (1)

Country Link
CN (1) CN116974620A (zh)

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN117520019A (zh) * 2024-01-05 2024-02-06 杭州玳数科技有限公司 一种组件通信方法及装置
CN117555645A (zh) * 2024-01-12 2024-02-13 腾讯科技(深圳)有限公司 基于多端应用平台的数据处理方法、装置、设备及介质

Cited By (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN117520019A (zh) * 2024-01-05 2024-02-06 杭州玳数科技有限公司 一种组件通信方法及装置
CN117520019B (zh) * 2024-01-05 2024-04-09 杭州玳数科技有限公司 一种组件通信方法及装置
CN117555645A (zh) * 2024-01-12 2024-02-13 腾讯科技(深圳)有限公司 基于多端应用平台的数据处理方法、装置、设备及介质
CN117555645B (zh) * 2024-01-12 2024-04-05 腾讯科技(深圳)有限公司 基于多端应用平台的数据处理方法、装置、设备及介质

Similar Documents

Publication Publication Date Title
US11741293B2 (en) Systems and methods of a script generation engine
CN110134378B (zh) 应用程序创建方法及装置、计算机设备及存储介质
US7610545B2 (en) Annotations for tracking provenance
CN110806868B (zh) 一种单页面搭建及加载方法
CN116974620A (zh) 应用程序的生成方法、运行方法以及相应的装置
US8850388B2 (en) Controlling application features
CN108920496B (zh) 一种渲染方法及装置
US20080244541A1 (en) Code translator and method of automatically translating modeling language code to hardware language code
CN110580174B (zh) 应用组件生成方法、服务器及终端
CN113064593B (zh) 移动app动态化的方法、装置、计算机设备及存储介质
CN102693238B (zh) Widget应用方法、系统及多媒体终端
CN112306486B (zh) 一种界面生成方法、装置、服务器及存储介质
CN103425469A (zh) 基于mda技术的手机游戏代码生成方法
KR101416096B1 (ko) 하이브리드 웹 어플리케이션 개발을 위한 호환성 높은 플러그인 시스템
CN112631563A (zh) 基于框架的系统开发方法、装置、计算机设备及存储介质
CN111488144A (zh) 一种数据处理方法以及设备
JP4836412B2 (ja) グラフィカル・ユーザ・インタフェースを生成する方法および装置
Simonsen PetriCode: a tool for template-based code generation from CPN models
CN113641594B (zh) 跨端自动化测试方法以及相关装置
CN114527979A (zh) 一种生成多端表单交互页面的方法及系统
CN116595284B (zh) 网页系统运行方法、装置、设备、存储介质和程序
CN115981750B (zh) 一种基于递归算法的组件配置方法
CN112685049B (zh) 一种java字节码编译方法
CN112988136B (zh) 一种用户界面编辑方法及装置
CN111694723B (zh) 产品在h5下运行时对节点及组件编辑的方法、存储介质

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication