以下是我在网易云课堂的关于产品前端架构方面的学习笔记,其实有很多也只是记下来了,但是我还没有真正的消化理解。所以本文将持续修改,对自己不理解的知识点,逐渐拓展补充。
本文主要涉及开发角色分类,版本管理,模型模块的选择以及一个具体的实例。
无意中看到另外一个同学在github上基于本课制作的电子书:也把链接附在此处,大家一个参考学习。
@(书籍阅读)[网易云课堂|前端架构]
产品前端架构
协作流程
Web系统
客户端与服务器端之间的相互交互;
Web系统在服务器端是如何组织的?
M: 数据层,存储应用相关数据,封装对数据的管理;
V: 数据模型,提供人机交互;
C:负责在模型和数据之间 传递数据,根据用户的输入修改模型,根据修改后的数据更新视图;
视图层需要的技能;
- Photoshop:切图;
- CSS,HTML:布置页面;
- JavaScript:动态
- TEMPLATE:将改变HTML注入DOM的方式,借助模板,生成由JavaScript变量驱动的长串HTML标记变得很容易,还能跟程序的业务逻辑分开;
-
Java/PHP/Node...
:后台操作;
老的前后端分离方法的弊端
- 后期维护性差;
- 专业化程度低;
- 需求响应速度慢;
前端包括视觉,交互逻辑,模板转换等;
随着技术的发展,控制层也可能部分由前端负责;
角色定义
- 视觉工程师
- 前端工程师
- 后端工程师
前端工程师的知识技能
- 页面工程师
- 精通切图技术(PS);
- 精通页面制作技术(CSS,HTML);
- 熟悉前端开发技术(JavaScript,template);
- 了解后端开发技术(Java,Node...)
- 前端工程师
- 精通页面技术(CSS,HTML);
- 精通前端开发技术(JavaScript,template);
- 熟悉切图技术(PS);
-
了解后端开发技术(Java,Node);
协作流程与规范
核心输出:
- 页面入口规范:
- 同步数据规范:
- 异步接口规范:
后期维护
职责说明
- 页面工程师
- 切图,优化图片
- 页面制作,优化页面效果和结构
- 完成简单的前端业务逻辑开发;
- 前端工程师
- 主导制定前后端分离规范;
- 主要前后端联调对接测试;
- 系统前端的设计架构,满足一定的非功能性需求;
- 完成前端的业务逻辑的实现,优化实现逻辑;
- 后端工程师
- 协助制定前后端分离的规范
- 协助前后端联调对接测试;
- 完成后端逻辑实现;
角色与人的关系?
- 复杂项目,页面工程师与前端分开,简单可能页面和前端是一个人;
接口设计
概述
URL地址:需要映射到那些模板,那些事API载入;
视图模板:
API接口:输入输出信息;
Model:数据模型,数据类型的格式等
页面入口的规范:
- URL与API
- URL与TEMPLATE;
- 基本信息
- 输入参数
- 模板列表
- 接口列表
同步数据
- TEMPLATE与MODEL
- 基本信息:对数据模型的说明
- 预填数据
- 注入接口
异步接口:
- API与MODEL
- 基本信息
- 输入数据
- 输出结果
规范的应用
- 构建项目结构
- 模拟同步信息
- 模拟异步数据
本地开发
本地模拟服务器做的事情?
本地代理?Local Proxy,根据配置信息。
联调
去掉本地环境,通过配置文件进行控制。
版本管理
简介
- 版本控制系统
- 分支模型
- Git
- Git介绍
- Git命令详解
版本控制系统
版本控制系统VCS(version control system):是一种记录若干文件的修订记录系统,它帮助我们查阅或者回到某个历史版本;
- “人肉”VCS
- 没有版本控制系统
- LVCS本地
- RCS,本地版本数据库管理版本。
- 不利于多人管理
- CVCS集中式
- 利用中央服务器来进行管理;
- 可控性更高;
- 影响流浪性;
- 单点故障;
- 如SVN
- DVCS分布式
-Git
-本地一直存在一个完整的版本,可以两个版本进行版本比较;
1.集中式版本控制系统
有一个中央服务器,干活的时候,用的都是自己的电脑,需要先从中央服务器获取最新的版本,然后开始干活,干完活了,再把自己的修改推动给中央服务器。
缺点:需要联网的情况下才能使用,上传速度慢。
2.分布式版本控制系统
分布式版本控制系统没有中央服务器,每个人的电脑上都用一个完整的版本库,只要交换对方的修改就行,把各自的修改推送给对方。
分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
优点:安全性高,不需要联网
分支模型
分支和分支模型
分支:
从目标仓库获得一份项目拷贝,每条拷贝都有和原仓库功能一样的开发线
分支模型(branching model)/工作流(workflow):
一个围绕项目[开发/部署/测试]等工作流程的分支操作(创建,合并等)规范集合。
产品级的分支模型
- 常驻分支
- development分支,开发分支
- 从master创建
- production(master),产品分支
- 默认分支
- development分支,开发分支
- 活动分支
- feature(特性分支)
- 从development创建
- hotfix:hotfix-36,代码修复分支
- 从master创建
- release:如release-110
- 从development分支创建
- feature(特性分支)
分支模型-特性开发
分支模型-发布线
涉及到的环境
- 开发环境
- 测试环境
- 预发布环境
- 生产环境
git介绍
git是什么?
- git是一个免费开源的分布式版本控制系统(DVCS);
- git是一个基于内容寻址的存储系统;
- 历史:git的出现离不开linux
- 1991-2002:几乎无版本控制器(patch包)
- 2002-2005:BitKeeper
- 2005-至今:git!!
- 优势
- 快!
- 完全的分布式
- 轻量级的分支操作
- Git已经成为现实意义上的标准
- 社区非常成熟活跃
- git的流行离不开github
- 安装
- window:msysgit
- Mac:brew install git
- apt-get install git
Git命令详解
help、config、status、init、add、rm、commit、log、diff、File级别的checkout、reset
- 超过100个命令
- 基本操作
- git config:配置git
- 配置级别
- local【默认,高优先级】:只影响本仓库.git/config
- global【中优先级】:影响到所有本地用户的git仓库~/.gitconfig
- system【低优先级】:影响到全系统的git仓库/etc/gitconfig
- git init 初始化仓库
- git status查看Git信息
- 未跟踪<->跟踪
- 内容状态:标识文件内容的改变;
- 工作目录
- 暂存区
- 提交区
- 文件状态
- 未跟踪
- 已跟踪
- 内容状态:标识文件内容的改变;
- 工作目录<->暂存区
- 可以同时出现两个文件
- 暂存区<->最新提交
- 未跟踪<->跟踪
git add:未跟踪变为已跟踪
git add.添加所有当前目录下的文件
忽略文件.gitignore
- 在添加时忽略匹配的文件
- 仅作用于未跟踪的文件
从暂存区删除git-rm
- git rm --cached :仅从暂存区删除
- git rm :从暂存区和工作目录删除
- git rm $(git ls-files -- deleted):删除所有被跟踪但是在工作目录被删除的文件
git commit
根据暂存区的内容提供一个提交命令
基于文件内容进行管理
git commit-a 工作目录已跟进
git log
git中别名的设置
git config alias.shortname
dit diff:显示版本差异
- 工作目录与暂存区的差异;
git diff-cached[] - 暂存区与某次提交的关系
- 撤销本地修改
git checkout --
将文本内容从暂存区移到工作目录;
git reset HEAD
将文件内容从上次提交复制到暂存区
撤销全部的改动
git checkout HEAD --
branch、checkout、reset、reset-vs-checkout、merge、rebase、rebase-vs-merge、tag
--
的用途
--
是用来解决文件和分支重名的冲突。
例如:
git checkout将文件内容从暂存区复制到工作目录;
git checkout从当前分支切换到 分支。
当filename和branch同名时会产生冲突,因此使用 -- 来指定此时的chechout是对文件的操作,而不是对分支的操作。
git checkout HEAD --
的作用:
当某文件在暂存区与工作目录中的内容不一致时, 使用git checkout HEAD --,会将最后一次提交(HEAD)的内容复制到工作目录。
同时,不管之前暂存区和最后一次提交(HEAD)的内容是否相同,暂存区都会跟着工作目录一起被复制为最后一次提交的内容。
分支操作
git branch:分支的增删查改都要依靠这个
master会始终指向最新的提交
轻量级:文本文件
get checkout
:通过移动Head 检出版本,可用于分支切换
git checkout next
;
提交随着head走
git checkout -
恢复到上一个分支
git branch -v
当前所有分支
detached head
一般不要再操作而只是读取内容;
get reset
将当前分支回退到历史的某个版本
将当前内容复制到暂存区;
git reflog
:按之前经过的路径,按需来排,利用hash来定位
使用捷径
A^:A上的父提交
A~n:在A之前的前n次提交
reset
和checkout
两个作用范围
commit
操作
file
操作
$ git checkout next
git stash
保存目前的工作目录和暂存状态,并返回干净的工作目录;
stash相当于一个栈
stash pop = stash apply + stash drop
git merge
:合并分支
解决merge冲突
git rebase
:任何状态上的提交,变基;
git rebase -- onto
rebase和merge的对比
- 不要在公有分支使用rebase;
git tag
:对某个提交设置一个不变的别名;
push、remote、fetch、pull、clone
远程操作
Git支持本地协议,所以我们可以初始化一个本地的远程服务器
git init ~/git-server --
git push
:提交本地历史到远程;
如何避免重复输入URL
git remote
:配置远程映射;
push
冲突(有人先提交了)
git fetch +merge
git pull
=git fitch
+fit merge
;
git clone
克隆远程仓库作为本地仓库;
git fetch 从远程获取最新版本到本地,不会自动merge
git pull 从远程获取最新版本并merge到本地,git pull = git fetch + git merge
git pull 过程不可控,一旦出现问题,很难定位问题;另外,本地工作目录会被远程分支更新
其它参考资料
- git 简明指南
- Pro Git
技术选型
模块组织(js脚本)
语言的模块支持
java:import
c#:using
css:@import
javascript:none!
模块和模块系统
- 一个模块属于一个模块系统;
- 封装实现
- 暴露接口
- 声明依赖
反模式:没任用任何模块系统的
缺点: - 封装性无
- 接口结构不明显
- 没有依赖声明
- 使用全局变量
IIFE:字值型的函数表达式
局部作用域,通过return输出接口
命名空间:
返回所有模块
依赖管理
模块系统
- 依赖管理
加载/分析/注入/初始化 - Commonjs/module
- 依赖管理成熟可靠
- 社区活跃,规范接受度高
- 运行时支持,模块定义非常简单
- 文件级别的作用域隔离
- 可以处理循环依赖
- 缺点是不是标准组织规范
- 同步的require,没有考虑浏览器环境
- webpack,browserify
- AMD
- 天然作用于异步的环境
- 依赖管理成熟可靠
- 社区活跃,规范接受度高
- 转为IO环境打造,适合浏览器环境
- 支持类似Commonjs的书写方式
- 通过插件API可以支持非js资源
- 成熟的打包工具
- 缺点:模块定义繁琐,需要额外嵌套
- 只是库级别的支持,需要引入额外的库
- 无法循环依赖,
- ES6
- 是真正的规范,未来的模块标准
- 语言级别的关键字支持
- 适应所有JavaScript运行时,包括浏览器
- 同样可以处理循环依赖
- 缺点是规范未达到稳定级别
- 基本还没有浏览器支持
- 鲜有项目使用
决定模块写法
- systemJS
模块转换工具:
browserify :实现浏览器读取CommonJS模块
webpack :同时支持CommonJS和AMD形式的模块,对于不支持的模块格式,还可以对模块进行shimming
uRequire :支持多种格式之间的互换,但暂时不包括ES6
systemJS :几乎支持任意资源
框架
库Lib
- 针对特定问题的解答
- 不控制应用程序
- 被动的被调用
框架frame - 控制反转
- 框架在具体的时间调用库
- 决定应用程序生命周期
- 一般会集成大量的库
解决方案: - DOM
- Communication
- Utility
- Template
- Component
- Routing
- 架构
开发效率
可靠性:浏览器兼容性/测试覆盖
更好的配套:文档/DEMO/工具
设计得更好
专业性
不适合使用框架的情况:
问题过于简单,备选框架质量与可控性无法保证;
无法满足当前业务需求;
团队中已有相关积累;
开放:基于一个外部模块系统,自由组合;
半开放:基于一个定制过的模块系统,内部-外部解决方案共存;
大教堂:深度定制的模块系统,很少需要引入外部模块;
Dom、通信、模板、utility、组件、路由、MV*架构.分别推荐解决方案
DOM
- selector/DOM操作/事件/方法
- 提供便利的Dom查询/操作/移动等操作
- 提供事件绑定/事件代理等支持
- 提供浏览器特性检测,UA侦测
- 提供节点属性,样式,类名等操作
- 所有上述操作实现目标平台的跨浏览器支持
jQuery
zepto.js:移动端的首选;
mootools;原生Dom对象:最好的源码阅读学习的资源;
概念清晰,没有包装对象,接口设计优秀,源码清晰易懂,不局限于Dom和Ajax;
手势:Hammer.js
局部滚动:iscroll.js
Velocity:高级动画
video.js:视频播放
Communication
- 处理与服务器的请求与响应
- 预处理请求数据/响应数据Error/Success的判断解读
- 多种类型请求,统一接口(xmlHTTPRequest1/2,JSONP,Iframe)
- 浏览器兼容
Reqwest:非常小;
优点:
- JSONP支持
- 稳定/IE6 +支持
- CORS跨域
- Promise/A支持
qwest:非常小,2.5k,支持浏览器少
优点:
- 更小的代码量
- XmlHttpRequest2
- CORS跨域
- 支持高级数据类型ArrayBuffer,Blob,和FromData
实时性要求极高的产品?易信web版?
socket.io
实时性
支持二进制数据流
只能自动的回退支持(非二进制数据)
多种后端语言支持
Utility:
- 函数工具包
- 提供js原生不提供的功能
- 方法门面包装,使其易于使用
- 异步队列/流程控制等等
- Shim:需保证实现与规范一直
Template:
String-based:dustis.js,hogan(mustache实现之一)dot.js(速度快)
模板+数据=展现
Dom-based:Angularis.jsVue.js,Knockout
运行时性能更好,局部更新
living-template:Regularjs,Ractivejs,htmlbar
拼接了字符串模板和dom模板
Component:组件
Modal/Slidar/DataPicker/Tabs/Editor
职责:
提供基础组件CSS支持
提供常用组件Slider,Modal
提供声明式调用
Bootstrap/Foundation
Routing
监听url变化,并通知注册的模块
通过JavaScript进行主动跳转
历史管理
对目标浏览器的支持
做什么的?
page.js:类似Express.Router
Director.js:前后端使用一套规则定义
stateman:深层
crossroads
Architecture(目的:解耦)
MVC/MVVM/MV*
提供一种范式,帮助(强制)开发者进行模块解耦
视图模型分离
更容易进行单元测试
更容易进行应用程序扩展
Modal:数据层,模型层
View:展示友好的界面,数据定制的反应
ViewModal:view和Modal的粘合剂
UnitTest:
SPA:单页系统;
引入路由,
TodoMVC
数十种常用框架的比较;
开发实践
网易云音乐
交互需求:内容结构,需求变更,信息架构,异常提示等
系统分解:
- 注册登录密码系统,
- 系统主框架
- 顶栏
- 边栏
- 底栏
- 内容栏
- 每个模块又有下一节的细分;
接口设计:
- 发现音乐- 推荐
- 推荐banner同步
- 推荐歌单同步
- 推荐版单同步
- 推荐节目列表异步
- 推荐新碟列表异步
- 推荐单曲列表异步
- 数据类型
- 模板资源
- 异步接口
- 页面摘要
工程构建:
项目结构
- 后端模板
- 前端实现
- 初始代码
- 模拟数据
视觉说明:
- 组件提取,
- 通用元件
- logo,输入框,歌单,专辑,按钮等
- 通用列表:
- 符合组件:评论
- 浮层弹窗:
- 通用元件
- 组件封装
- BannerSlider
- 模拟数据
- 使用示例
- 结构模板
- 逻辑实现
- BannerSlider
- 逻辑实现
- 数据层实现
- 节目数据(program.js)
- 页面模板转换
- 页面入口
- 数据层实现
测试发布
本地测试
- 配置模拟数据
- 使用同步模拟数据
- 使用异步模拟数据
- 对接联调
- 去除同步模拟数据
- 去除异步模拟数据
发布上线
- 打包发布
- nej
- 打包配置
- 输入输出
- 优化配置
- 优化图片
- CDN配置
- 代码压缩
- 代码合并
- core mask