01|以电商网站的账号体系JS SDK分析前端业务架构的实现机制
本篇文章,我们将通过开发一个电商网站的账号体系JS SDK来分析一下前端的业务架构和相关最佳实践的应用。文章中,并不会涉及太多的的编码工作,主要是以分析思路为主。
一、账号体系JS SDK是什么
账号体系SDK,统一控制核心功能,对下游开放样式制定。
账号体系在大公司或者多产品的公司用处比较多,就以百度为例,百度网盘、百度地图、百度App以及百度官网等所有百度产品,他们从注册到登录的整个流程都是一致的,可能因为产品的差异,会在样式方面存在一些差异,这里就用到了账号体系,保证了公司整条业务流水线的统一,降低了后期维护的成本。
二、需求分析
在项目的开始,我们首先要进行需求分析,要搞清楚下面的三个问题:
问题1:产品需要什么样的内容和效果?
问题2:技术上需要哪些工作达到产品要求?
问题3:技术上有哪些指标?
只有在清楚了上面上面的三个问题,我们才能够进行具体的架构设计,之后才会进行入相应的编码工作。
(一)、产品要求
1、包含登录/注册/找回密码/信息设置与修改
账号体系应当包含一些基础的业务功能,如注册,登录、密码找回以及对输入信息错误的提示等。
2、支持pc端和移动端,各个子网站需要有不同的样式。
3、功能逻辑必须统一
就拿淘宝和天猫来说,整个的账号体系是功能是要保证一致的,不能出现一个使用电话注册,而另外一个使用邮箱注册。
(二)、技术应对
1、通过JS SDK的方式,由一个团队统一开发维护,保证功能的统一以及修改的同步。
2、支持PC和移动端,因此包的体积要小,要分包,不能有依赖。
3、JS SDK要包含全部的业务逻辑,但不包含具体的样式,由下游业务放进行自定义。
(三)、前端的技术指标
1、浏览器兼容到IE8
2、支持PC和移动端,大小不能超过30kb
3、支持多种引用方式:直接引用,commonJS,AMD
三、前端架构设计
(一)、自顶向下,自外而内
对于我们的这个项目,首先要从用户最先接触的地方开始设计,也就是对外的API设计,然后再进行相应的模块设计,比如注册、登录、密码找回,在完成具体模块的设计之后,对模块中相似的,复用性比较多的代码进行封装,以公用模块或组件的方式共其他模块使用。
1、对外的API接口设计
a.暴露什么样的接口?(类/普通函数/对象)
b.有哪些配置项?
c.默认值是什么?
2、模块的划分与关联
如何编写公共模块?
a、对外暴露函数: 单一功能,且无内部状态
b、对外暴露对象: 无关联功能集合
c、对外暴露class(构造函数):相互关联的功能集合或存在内部状态的功能。
<script>
var login = pass.login({
container: document.getElementById('login-container'),
autocomplete: false,
success: function(){
location.replace('profile.html')
}
})
</script>
模块的划分与关联

模块的具体实现与一般性套路
如何编写业务模块
a)、init: 初始化,用于接受参数和设置初始值
b)、render:渲染
c)、event:事件绑定
示例:
案例结构:
login
---init.js
---render.js
---event.js
login/init.js
import render from './render.js'
import event from './event.js'
window.login = (opts) => {
const container = opts.container;
render(container)
event();
}
login/event.js
export default () => {
const btn = document.getElementById('submit');
btn.onclick = () => {
alert('111')
}
}
login/render.js
export default (container) => {
let tpl = `<form id=""form>
<input id="input" name="name" type="text"/>
<input name="password" type="password"/>
<input value="登录" id="submit" type=“submit” />
</form>`
container.innerHTML = tpl;
}
.html
<script src="./init.js"></script>
<script>
login({
container: document.getElementById('container')
})
</script>
编写公共模块
login
--common
----formCheck.js
--init.js
--event.js
--render.js
event.js
import formCheck from './common/formCheck'
export default () => {
const btn = document.getElementById('submit')
const input = document.getElementById('input')
const check = formCheck(document.getElementById('from'))
btn.onclick = () => {
check()
}
btn.oninput = () => {
check()
}
}
formCheck.js
export default (form) => {
return () => {
alert(form.id)
}
}