Jerry在2020 SAP全球技术大会的分享:SAP Spartacus技术介绍的文字版
这是Jerry 2020年的第86篇文章,也是汪子熙公众号总共第268篇原创文章。
这篇文章的视频版本如下:
这个分享是SAP 2020全球技术大会(SAP TechEd),“客户自主”时代的极致体验分论坛内容之一:
本文的分享主要分为以下四个方面来介绍Spartacus.
首先,通过Spartacus四大特性的介绍,让大家对作为SAP Commerce Cloud新一代Storefront这个电商前台店铺应用有一个直观的了解。Spartacus的首页如下图所示,其logo是一个印有闪电的购物袋,象征着Spartacus能为用户带来流畅快捷的在线购物体验。
其次,通过和Commerce Cloud原有的基于Accelerator技术的Storefront相比较,让大家了解SAP推出Spartacus的原因是什么。
紧接着,是Spartacus技术架构的简要介绍。
最后,可能是SAP Commerce从业者比较关心的一个话题,即Spartacus的发布方式和更新频率,因为这个话题也和广大Commerce从业者是否决定选择Spartacus密切相关。
SAP Commerce Cloud是SAP一款电商解决方案,而Storefront这个术语,指的是该解决方案的前台店铺界面。一句话概括Spartacus,它是基于现代Web开发技术和框架打造而成的一款新的SAP Commerce Cloud Storefront.
那何谓现代呢?Spartacus 1.0版发布于2019年7月,因此相比前一代基于Accelerator技术的Storefront来说,Spartacus具有得天独厚的优势,能够采取比较成熟和现代的前端技术来开发。
Spartacus特性之一:单页面应用 - Single Page Application
这也是Spartacus命名的由来。所谓单页面应用,是由一个称为外壳(shell)的html页面和多个包含具体业务逻辑的页面片段组成。
Commerce传统的Storefront,基于JSP实现,JSP是一种服务器端渲染技术,页面代码在Commerce服务器端生成。而单页面应用是一种富客户端技术,页面片段的渲染以及页面路由,放在客户端完成,这样减轻了Commerce服务器的负载。当单页面应用的界面内容发生变化时,不需要重新加载整个外壳html页面,而仅仅需要更新相关的发生变化的页面片段,这样较多页面应用相比,页面之间的切换更加流畅,用户体验更好。
Spartacus特性之二:响应式设计和自适应设计
这是web应用的用户体验领域两个容易混淆的概念,因为二者都是为了解决网页在不同屏幕尺寸的设备上展示的问题。从编程角度讲,响应式设计通过各种前端技术,为页面元素赋予了根据屏幕分辨率的变化而自动调整显示行为,以达到最佳显示效果的能力。
例如Spartacus里的列表控件,随着屏幕宽度的减小,显示的列表栏的数目也随之减少。而自适应设计,为不同类别的设备分别实现不同的页面,检测到设备分辨率后调用对应的网页。
Spartacus的页面设计绝大部分是响应式布局,但也支持自适应布局的特性。
Commerce的CMS模块将Storefront UI按照功能上的逻辑相关性,划分成不同的区域,而Spartacus可以允许使用者根据不同的屏幕尺寸,配置在该尺寸下,不同的区域内应该显示哪一些UI组件。
Spartacus特性之三:100% API 驱动
Commerce Cloud提供了一组称为Omni Commerce Connect ( 简称OCC ) 的Restful API.
Spartacus通过标准的HTTP协议调用这组API,实现同Commerce Cloud交互的目的。从编程层面来说,100%的API驱动确保了Spartacus的前后端分离,使得Spartacus的二次开发人员不需要去了解Commerce平台Java层的实现细节,而过去基于Commerce Accelerator技术的Storefront二次开发,需要的是会使用JSP和Java的全栈开发者。
从更深层次来说,100% API驱动使Spartacus同Commerce平台也解除了紧耦合关系,从而极大提升了Spartacus的可升级性。这一点在接下来Accelerator同Spartacus的对比中我们会进一步说明。
Spartacus特性之四:开源,免费
Spartacus的代码是完全开源的,托管在Github上。如果大家细心察看Github仓库上的代码提交者列表,就会发现,这些代码贡献者有的是像Jerry这样的SAP职员,有的来自partner公司,还有freelancer即自由职业者。SAP选择将Spartacus开源,希望构建出一个繁荣的生态圈,和开源社区里其他贡献者共同在Commerce Storefront领域进行持续创新。
那么,SAP为什么要推出Spartacus呢?这得从Spartacus诞生之前,SAP Commerce传统的Storefront实现技术即Accelerator说起。
Accelerator是Spartacus发布之前,SAP Commerce Cloud使用的Storefront实现技术。
Accelerator是一个开箱即用的web实现模板,是Commerce平台的一部分,以源代码的方式交付给客户。客户通过一个叫做module generator的工具,基于Accelerator 模板代码生成自己的Storefront实现,然后基于这些生成的代码继续二次开发。这种源代码生成方式确实能加快客户的Storefront二次开发速度,这也是Accelerator命名的由来。
然而,Accelerator这种同Commerce平台的紧耦合关系,以及基于源代码级别的二次开发方式,给Commerce项目实施的可升级性带来很大的挑战。
例如,当客户发现新版本的Accelerator能满足自己新的业务需求时,希望升级Accelerator. 然而由于Accelerator是Commerce平台的一部分,所以必须先升级整个Commerce系统,再使用module generator基于高版本的Accelerator代码,重新生成自定义实现,再把基于低版本Accelerator模板而进行的二次开发内容,逐一手动地迁移到高版本Accelerator生成的自定义实现中去。
当Commerce的二次开发达到一定规模量的时候,这种手动升级的方式很挑战。
Accelerator具有的这些缺陷,在Spartacus问世之后都迎刃而解。
Accelerator通过源代码的方式提供了一个Storefront的开发模板,而Spartacus则以库的方式,提供了一个轻型的Storefront开发框架。我们新建一个Angular应用,导入对Spartacus库的依赖,当我们需要升级Spartacus时,只需要更新Angular应用的package.json文件里Spartacus库文件的版本号即可,因此Spartacus从可升级性上来说是一个巨大的飞跃。
Spartacus采用API的方式同Commerce交互,这使得Spartacus可以同Commerce分开部署,分别进行升级,比如目前已经发布的Spartacus 3.0,支持从Commerce 1905开始及其之后的所有版本。
Spartacus采用Angular开发,编译之后生成JavaScript代码,作为其运行时语言。这样一来,使用Spartacus的二次开发人员,不再需要像过去开发Accelerator那样,不再需要掌握前端JSP和后端Java的全栈开发技术栈。
Accelerator的可扩展性,是通过牺牲可升级性为代价换来的。同Accelerator只有源代码级别的修改这一单一的扩展方式相比,Spartacus实现扩展性的手段更加多元化。
(1) Spartacus的模块之一,ConfigModule,将业务逻辑和页面布局以及样式,通过配置的方式暴露出来。二次开发人员通过调整配置,可以更改Spartacus默认的行为和页面布局以及样式。
(2) Spartacus的页面布局由不同的Angular组件组成,这些Angular组件同Commerce的CMS组件具有一一对应关系。Spartacus允许二次开发人员增强甚至开发新的Angular组件,去替换Spartacus发布时使用的默认组件,以此来实现客户的页面定制化需求。
(3) 借助Angular强大的依赖注入机制,Spartacus允许开发人员像Commerce后台开发人员使用Java Spring框架那样,开发自己的service实现。通过Angular的Dependency Injection机制,注入自开发的service,从而达到定制化Spartacus的运行流程和逻辑的目的。
下面我们来简要了解Spartacus使用到的一些技术栈和Spartacus同Commerce交互的基本原理。
前面说到,Spartacus是基于现代Web开发技术打造而成的一个Storefront开发框架。因此,涉及到的技术栈都是目前前端开发普遍使用的一些比较成熟的技术。
Angular:由Google维护的一款web前端开发框架,借鉴了大量有十几二十年历史的成熟的后端开发理念,比如依赖注入、接口、注解等等,这些理念在开发 需要持续迭代和维护的大规模企业级前端应用时,显得特别有优势。Angular同时也是一款与时俱进的框架,比如对TypeScript的支持,跟RxJS的深度整合,对Progressive Web Application即渐进式网页应用理念第一时间的支持等等。
Spartacus 1.0 基于Angular 9,而目前最新的Spartacus 3.0, 基于Angular 10. 上个月Google发布了最新的Angular 11,目前我们团队的架构师,正在评估Spartacus支持Angular 11的技术可行性。
TypeScript: Angular的开发语言是TypeScript,ES5, ES6是JavaScript发展过程中出现的两个版本,而TypeScript不仅是ES6的超集,而且是一门静态类型编程语言。2018 年有一份前端项目中出现频率最高的十大错误类型统计报告,其中前7位都和类型错误有关:
https://rollbar.com/blog/top-10-javascript-errors/
而TypeScript的编译器 静态类型检查,可以避免不少的类型错误。通过强类型接口,在服务实现者和服务调用者之间创建了一种契约,这种契约能降低Spartacus组件和服务之间的耦合性,帮助像Spartacus这种其开发者来自世界各地的开源项目进行更有效率地开发。
Rxjs: Reactive Extension JavaScript,是一种响应式编程实践,Angular是RxJS这个库的重度使用者。Rxjs的核心是Observable(可观察对象),Spartacus的实现,使用Rxjs的可观察对象,封装了从Commerce读取业务数据的异步操作。通过Rxjs提供的施加在可观察对象上的各种操作符,Spartacus可以灵活地控制异步读取Commerce业务数据的时序,对Spartacus和Commerce之间的数据流进行聚合或者拆分。
Ngrx: Angular应用使用的一个能够优雅的管理应用状态的库。Angular和其他主流的前端框架一样,遵循组件化开发的标准,组件间通信基本都是单向数据流:父组件通过属性绑定把数据传递给子组件,子组件如果想要修改传入的数据,必须通过事件回调同父组件通信。NgRx作为通信场景里的第三方,能够统一管理组件的状态,降低了Spartacus这类复杂前端应用组件间状态管理的复杂度和出错的可能。
SASS:Syntactically Awesome Stylesheets的缩写,是一种CSS的扩展语言,在CSS基础上增添了定义变量,支持代码块嵌套,继承,命名空间,父级引用等特性,大大提高了css的开发效率。可以说Spartacus能够支持从页面整体颜色风格,到控件外观 细粒度的微调,SASS功不可没。
Jasmine:一个前端单元测试框架。
Cypress:一个端到端的自动化测试框架。
我们通过完善的单元测试和端到端自动化测试,保障了Spartacus这种开源项目的代码质量。
最后,我们开发出的Spartacus,经过打包后,以库的形式发布到npmjs.com上去。
这是一张Spartacus同Commerce交互的示意图。我们首先看图的最右边。Spartacus同Commerce系统的通信,通过HTTP协议调用OCC API完成。Connector是HTTP调用的发起者,维护了静态的配置信息,即API的endpoint.
比如,从Commerce系统读取产品主数据,读取的字段列表以url参数的形式出现在API endpoint里。这些字段列表可以在Connector的静态配置点里进行配置。Connector并不会直接同Commerce交互,而是把请求转发给Adapter,具体通信由Adapter完成,Connector只负责调度Adapter. Spartacus发布的Adapter默认使用OCC Module,即Commerce标准的OCC Restful API,但是客户也可以实现自己的Adapter,连接Commerce之外的其他后台系统。
Connector将Adapter取回的数据交给NgRx的store结构统一管理,后者的复杂度被Façade层所隐藏,而Spartacus UI组件只会同Façade层交互,进行数据绑定和页面展示。这体现了关注点分离的设计原则。最后,因为UI组件和Commerce后台组件的数据模型存在差异,因此需要Converter,在数据从Commerce取回,准备呈现在UI之前,先要通过Converter转换成适合UI展示的结构;反之,在Spartacus提交数据准备写回Commerce时,也要先将数据通过Converter转换成OCC API接受的数据格式。
那么Spartacus github仓库里的源代码,通过什么方式发布给客户使用呢?
前面已经提到,Spartacus打包之后,以库的方式发布到npmjs.com上。这是一张Spartacus库文件之一,Spartacus Storefront托管到npmjs网站上的截图。这个库的版本号为2.1.3, 我们稍后会介绍其版本机制。
Spartacus库主要有三个实体组成:core, storefront和styles. 其中storefront包含了用户肉眼可见的,组成电商店铺应用外观的UI组件,客户可以重用和增强这个库文件里包含的组件。
Core这个库文件则包含了Spartacus的控制逻辑。用户可以开发自己的服务类,通过Angular依赖注入的机制,把自开发服务类注入到core框架之中。Styles包含了Spartacus的界面样式实现,客户可以对这些样式进行定制化,或者用自开发样式来覆盖标准样式。
之前进行Accelerator和Storefront的可升级性比较时已经提到过,客户基于Spartacus库文件进行Storefront二次开发,并不会直接修改Spartacus发布的源代码。客户的二次开发代码,和Spartacus库文件是一种松耦合的依赖关系。客户升级Spartacus版本,在绝大多数情况下都不会影响到已有的二次开发代码。那么所谓的“绝大多数情况下”,具体是指什么呢?这就要从Spartacus的版本管理机制说起。
同绝大多数流行的开源框架和库一样,Spartacus的版本管理也采取了所谓语义化版本的机制,版本号由主版本号,次版本号和修订版本号三部分组成,中间由小数点分隔开。
主版本号的升高,用于引入无法向后兼容的变更或颠覆性的更新。无法向后兼容的变更,是指Spartacus升级之后,之前基于低版本编写的二次开发代码,需要人工调整后才能继续工作。而颠覆性的更新,一个例子就是Spartacus升级到3.0版本之后,首次支持B2B的电商功能。
次版本号的增加:用于引入新功能,并且版本更新之后,已有的二次开发代码不需任何调整仍然能够继续正常工作。源代码重构,性能优化等不属于bug修复的修改,也通过次版本号的增加而引入。
修订版本号:主要用于发布bug的修复。
Spartacus的修订版本发布,以周为单位,确保使用过程中发现的bug能尽早得到解决。次版本的发布以月为单位,这种更新的频率有助于客户快速地进行持续改进和持续创新。
而主版本的更新,可以参考SAP官方路线图网站上的声明。
从上面这张截图中package.json里定义的依赖,我们能够发现之前讲到的core, storefront和styles 3个库,再加上主要包含了文档和翻译的assets库。
其中版本号2.1.0之前的这个符号^,有个术语叫做hat, 这是语义化版本管理机制里的范围标识符之一,表示这个Storefront二次开发工程支持主版本号为2,且次版本号大于1的所有Spartacus版本,但是不支持主版本号为3的Spartacus.
换句话说,图中这个二次开发项目,只支持SAP Commerce B2C的功能,因为B2B的功能是Spartacus 3.0版本里才引入的。
最后,让我们用一些关键字来总结今天的分享。SAP Spartacus诞生于2019年7月,是一款满足响应式和自适应特性的现代Storefront应用和开发框架。同之前的Accelerator Storefront相比,Spartacus在保留了原有的可定制化特性之外,具有更流畅的用户体验和良好的可升级性,并且本身开源,无需购买额外的license.
如果大家对Spartacus有兴趣想深入了解,可以去open SAP网站上学习Spartacus的公开课:
https://open.sap.com/courses/sparta0
感谢阅读。