今年,ReactJS首次为Globus大型连锁超市在线商店推出。 该项目很有趣,因为它扩展了Bitrix平台的功能,同时保留了为搜索引擎生成页面的功能,并且不会因重复代码和布局而混乱。 在本文中,我们讨论了如何使用适用于php的v8js模块将Bitrix组件与ReactJS组件连接,以及如何保存站点的主要部分。
为什么需要这个?
最初,在线商店网站的逻辑是建立在Marionette.js库上的。 几年前,这种逻辑得到了回报,但是随着时间的流逝,对前端功能的业务需求增长如此之快,以至于每次改进都伴随着严重的困难。 由于高负荷,前部的速度降低并且非常不理想。 为了解决这个问题,我们选择了ReactJS,但是在将页面渲染到后端然后将页面的一部分链接到React组件时出现了问题。 同时,我们的目标是逐步过渡到ReactJS,因为 巨大的变化可能会导致对前部进行彻底的重新设计,因此,选择取决于以下组件:
将迷你购物篮和产品卡转移到ReactJS的主要困难是两个组件中商品数量的即时同步,即 如果篮子中有3千克胡萝卜,则应在向篮子中添加物品的区域(拣选器)中显示3千克,并且当迷你篮子中的物品数量发生变化时,应在拣选器中进行更改,反之亦然。 另外,有必要平整后端请求的延迟,以使接口尽可能快地工作。

”
另一个复杂性是商店(食品零售)的特殊性,这里存在计件加权商品的概念。 这是一种以千克为单位的产品,但是用户购买了很多件,例如西瓜,客户无法全部购买,只能部分购买。 供用户使用的此类产品应以件数显示,但在后端以千克为单位。
您是如何解决问题的?
为了不复制1C-Bitrix和React系统模板中组件的布局,决定将其放置在React组件上。 React中的组件名称应与1C-Bitrix系统组件模板一致。 为了实现这样的想法,我们使用了:
- php的V8js模块;
- reactjs / react-php-v8js;
- webpack。
第一项是v8js模块,该模块应将我们的react组件转换为php环境中的静态布局。
以下是来自React Community的一个小型库,该库是一个包装,用于在v8js模块的js环境中更轻松地进行React初始化。
当然还有webpack,没有它。 与babel结合使用,它允许您使用jsx模板和es6标准来编写代码。 所有示例将以es6语法呈现。 这很简单,但是如果不能立即理解它,则应该为此刷新自己的记忆。
php的V8js模块。该模块是php的扩展,允许您使用V8 Javascript Engine在php中执行js代码。 安装非常简单,就像常规的PECL扩展一样。 最主要的是您在系统库和V8头文件中。
Webpack为了构建react和react组件库,我们使用webpack。 前后的汇编文件略有不同。 我们将要处理3个文件:
- initialize.js-> app.js-前端应用程序;
- reactServer.js-> reactBuild.js-服务器端的React库;
- components.js-> reactComponents.js-react组件的集合。
用于服务器渲染的程序集之间的主要区别在于,所有库和组件都必须放入全局对象中,并且库通过require函数连接。 由于某种原因,导入指令不起作用。
所有源文件都在本地/模板/ <模板名称> / src /目录中

项目的根目录是webpack.config.js-设置。

程序集文件的内容可以在文章末尾找到。
Npm和以下软件包必须安装:
- 巴别
- babel-cli;
- 网络包
- 反应
- 反应
- 下划线//可选。
通过运行以下命令完成组装:
$ webpack。
自定义bitrix模板引擎要在1C-Bitrix系统中注册自定义引擎,您需要将其设置添加到全局变量$ arCustomTemplateEngines。 在密钥中,您需要指定引擎的代码。 我们使用了“ JSX”。 在这些值中,您需要指定模板的文件扩展名,即呈现模板的功能。 最好指定一个小于100的排序,以使我们引擎的优先级高于标准。
使用以下方法创建JSXEngine类:
- setEngine-注册模板;
- 初始化-通过reactjs / react-php-v8js库包装器初始化v8js;
- 执行-模板渲染功能
以及用于呈现_JSXEngineExecute模板的包装函数,因为 1C-Bitrix系统需要注册特定功能。
为了不每次React实例都初始化时,请将其放在静态变量中并添加初始化方法。
reactjs / react-php-v8js库的ReactJS类中实现了一个特殊接口,以呈现react组件。 类构造函数将两个参数作为输入,其中应包含react模块的js代码以及通过webpack收集的项目中使用的所有react组件。 初始化后,我们可以渲染它们。 为此,请使用组件名称和props数组的参数调用安装组件的setComponent方法。 之后,getMarkup方法将显示组件的内容,而getJS将在前面显示用于绑定组件的js代码。 getJS方法需要参数中包含组件的html块的标识符。 为此,我们实现了一个简单的模板,用于将呈现的组件包装在html块中。 块本身的设置被传输到一个json文件中,该文件放在1C-Bitrix系统组件模板中。 设置以json格式存储。

将组件转移到新模板我们将使用标准菜单组件的示例显示组件到React的转换。 组件的布局已集成到标准模板引擎中。 React建议将功能分解为组件的策略。 此外,组件可能非常小。 直到超链接标签。 我们不会将菜单细分为这样的琐事,但是尽管如此,我们还是会进行一些分解。
我们的菜单最多可嵌套3级。 因此,将菜单功能分为3个反应组件(每个级别每个组件)是合乎逻辑的。 如果仔细看,您会发现第二级菜单项分为两列。 此功能应放在其他组件中。

因此,我们有4个组成部分。 我们将它们放置在src / components目录中的文件TopMenu.js,SubMenuLevel2.js,SubMenuLevel3.js,TwoColumnItem.js中(最后请参见其他组件的代码):

为了使我们的模板起作用,您需要为1C-Bitrix系统菜单组件创建一个模板。 模板的名称必须与react组件的名称匹配。 在模板内部,您需要将文件扩展名与我们的引擎设置相对应。 在文件内部,您需要指定将在其中呈现我们的react组件的html节点。
结果
该解决方案使您可以在后端和前端使用反应组件。 因此,显示功能的逻辑存储在一个地方,这极大地促进了项目的支持。
初始页面渲染的速度提高了将近1 s。 因为 现在,您无需重绘组件所在的房屋元素。 ReactJs可以即时获取它。 此外,弱设备上的元素闪烁也消失了。
将来,计划通过基于node.js的服务切换到后端侧的呈现组件,并实现一个页面应用程序,同时保留为SEO生成页面的功能。
应用程式
initialize.js

components.js

reactServer.js

SubMenuLevel2.js

SubMenuLevel3.js

TwoColumnItems.js
