Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

易企秀H5项目架构梳理 #13

Open
xiaoyu2er opened this issue Apr 16, 2018 · 6 comments
Open

易企秀H5项目架构梳理 #13

xiaoyu2er opened this issue Apr 16, 2018 · 6 comments
Labels

Comments

@xiaoyu2er
Copy link
Owner

xiaoyu2er commented Apr 16, 2018

回顾

在上一篇易企秀H5项目重构总结 中, 笔者详细记录了重构项目的缘由, 技术选型及实践, 灰度及 bug 修复, 编辑器功能边界划分及模块化实践, code review 实践 及 总结.

距离上次总结已经过去了一年的时间, 在这段时期, 笔者又基于当初的项目架构, 横向扩展了 wap 编辑器和 混合模式编辑器, 其中 wap 编辑器在线上正常运营, 而混合模式则碰到了很多技术瓶颈, 虽达到测试上线标准, 但是最终夭折腹中, 没有正式上线; 除此之外, 我与明纯 共同重构了另外一项复杂业务: 组合, 图层和功能模板. 最近, 有关组合, 图层的设计和一些复杂的算法明纯会在他的博客分享, 敬请期待 :D

8661515316159_ pic_hd
上图为 wap 编辑器

group3
上图是组合的操作

回过头看上一篇总结, 有些思想和方法是非常具有前瞻性的, 有些决定则看起来缺乏魄力, 显得略显保守. 接下来, 笔者将会就第一次重构进行复盘, 对目前项目的构建过程, 核心组件库, 编辑器架构等方面做最后一次易企秀 H5 项目的架构梳理.

第一次重构复盘

第一次重构的正确选择:

  • 淘汰 grunt, 采用 gulp + webpack, 大大提高了构建速度
  • 引入面向对象思想, 构建核心组件库, 至今组件库都是整个项目的基石. Core + 多编辑器实例构成了目前的多编辑器框架.
  • 引入 ES6, 面向下一代语言标准
  • 编辑器全指令+模块化开发
  • 积极 code review
  • 灰度方案

第一次重构时保守的选择:

  • 没有一开始就拥抱模块化标准, 采用了挂载全局变量的方式
  • 没有彻底的 OO 化, 对于触发, 动画, 事件系统等仍然采用面向过程式的编程
  • 没有做好是否使用新框架的调研 保守的采用了当时的 ng1 + jquery 的方案

重新来过, 有哪些可以做的更好

  • 明确目标, 拆分项目, 灰度方案, 技术选型, 重构和优化 应该分步走. 避免时间上无法量化的重构
  • 数据结构的梳理和规范应该是重构的第一步
  • 数据规范后应该采用 typescript 来开发项目, 从而规范和提升开发效率
  • 做好是否使用新框架的调研 或许一开始采用 vue 或者 react 可以解决现数据流动和 dom 操作的诸多问题
  • 积极做项目的抽象
    • 抽象出样式库 (避免后续的黑白模式修改起来费劲)
    • 抽象出基础组件库
  • 坚持 code review

架构梳理

构建方案

  • H5编辑器: webpack
  • H5预览: gulp + webpack

编辑器构建方案

所有编辑器都是相对独立的单页 app, 使用 webpack 进行构建

  • util.js 提供了对本地构建的版本号 (格式: ${git-commit-hash}_${time})
  • webpack.helper.js 提供 webpack 公共的构建逻辑, 其中使用了
    • loaders
      • file-loader 处理静态文件
      • html-loader 处理 html 文件的压缩
      • scss-loader, less-loader, css-loader 处理样式文件
      • babel-loader, awesome-typescript 处理 ts 文件
      • ng-annote-loder, babel-loader 处理 js 文件, ng-annote 处理 ng 的依赖注入
    • plugins
      • CleanWebpackPlugin 清理构建文件
      • WebpackZipPlugin 生成 zip 打包文件
      • ExtractTextPlugin 内联 CSS 抽出文件
      • UglifyJsPlugin 压缩 js 文件
      • HtmlWebpackPlugin 根据模板生成 index.html
  • 使用 webpack-dev-server 进行热更新构建
  • webpack.config.js 通过 yargs.argv 判断构建的编辑器入口, 调用 webpack.helper.js 构建

H5 预览构建方案

H5 浏览项目构建流程相对复杂, 采取 webpack 处理程序逻辑打包 + gulp 处理流程 的方式 进行构建

  • 使用 webpack.view.js 打包所有资源
  • 使用 gulpfile 处理其余流程
    • build:inject index.html 注入静态资源链接
    • index:ftl, index:mobile, 根据 index.html 生成后端模板和移动端模板
    • css:http 移动端模板中对 css 中的资源文件, 需要把相对路径转变成绝对路径
    • check 检查生成的资源是否完整
    • zip-all, zip-ftl 打包静态资源

项目梳理

  • core: 核心组件库
  • view: H5 预览
  • editor: H5 编辑器
  • wapEditor: wap 编辑器
  • metaEditor: 标签编辑器
  • appEditor: 混合模式编辑器

目录结构梳理

顶级目录
├── README.md 项目说明
├── build 构建目录
├── docs 文档目录
├── env 环境目录
├── eqxiu.json 自动化部署配置
├── gulpfile.view.js H5预览 gulp 配置
├── node_modules
├── package.json
├── src 源文件目录
├── tsconfig.json typescript 配置
├── types
├── util.js 构建工具的 util
├── webpack.config.js webpack
├── webpack.helper.js 公共 webpack 配置
├── webpack.view.js H5 预览 webpack 配置
源码目录 
src
├── appWpEditor app 混合模式
├── common js common
├── core 核心组件库
├── editor 编辑器
├── metaWpEditor 贺卡编辑器
├── ngcommon ng common
├── view H5 view
└── wpeditor wap 编辑器

Core 核心组件库

核心组件库维护了所有易企秀H5的所有核心组件及其内在逻辑

核心类及继承关系

  • EqxScene 场景
  • EqxPage 页面
    • EqxLongPage 长页面
    • ...
  • EqxLayer 图层
  • EqxPageEffect 页面特效
    • FingerEffect 指纹特效
    • ...
  • EqxItem 组件基类
    • EqxGroup 组合
    • EqxComp 组件
      • EqxText
      • EqxImage
      • ...
      • EqxForm
        • EqxCheckbox
        • EqxRadio
        • EqxDropDownList
        • EqxInput
          • ....
      • wx 微信组件
        • EqxWxImage
      • ...

辅助类

  • ProgressBar 进度条
  • EqxArrow 翻页箭头
  • ...
  • EqxPageScroll
    • 策略模式
    • book, card, cube, fadeIn, fall, flip, horizontal, horizontalinertia, horizontalPush, horizontalSingle, scale, swap, vertiaclinertia, vertical, verticalPush, verticalSingle
  • 工厂
    • PageFactory 页面工厂
    • CompMap 组件工厂
    • PageEffectLoader 特效异步加载工厂
  • manager
    • EqxCommentManager 评论管理
    • EqxFormManager 表单管理
    • EqxSoundManager 音效管理
    • EqxStatManager 统计数据管理
    • EqxScreenManager 幕管理
    • EqxGroupManager 组合管理
    • EqxFtManager 功能模板管理
      • EqxFtRule 功能模板规则
      • EqxFtTerm 功能模板条款
      • EqxFtEditPropManager 功能模板组件可编辑元素管理

H5 预览流程梳理

view预览步骤

  1. 获取场景的基本信息(id, code...)
  2. 根据用户类型调整 API 域名
  3. 获取加载页的配置
  4. 获取用户微信里的信息
  • 从缓存里取用户信息 如果有就直接用
  • 如果没有 请求用户授权
  1. 获取场景列表的数据, 矫正数据 (adapter)
  2. 微信信息获取后 pv打点和微信组件设置
  3. 渲染场景

易企秀 JavaScript 风格指南

编辑器架构

参考 易企秀H5项目重构总结 编辑器功能边界划分及模块化实践, 核心思想并未发生变化, 摘录如下

编辑器理念

  1. 数据驱动
  2. 依赖组件库.
    为了保证编辑器和预览时组件渲染一致, 编辑器将所有和渲染相关的逻辑全部交由组件库.
  3. 全指令 + 模块化
    笔者考虑到未来的团队合作, 希望尽早开始模块化的尝试, 参考了以下文章
    Angular 1.x和ES6的结合 xufei/blog#29 Angular 1.x和ES6的结合
    Angular1.x + ES6 开发风格指南 kuitos/kuitos.github.io#34 Angular1.x + ES6
    笔者决定, 升级 ng1.2 至 1.5. 整个项目采用 ES6 + (webpack + gulp)+ 全指令的形式进行模块化的重构.
  4. service 做到 简易统一的 API; 职责单一; 少依赖; 可复用
  5. 编辑区鼠标操作全部重写

经过项目拆分, 笔者划定了项目的整个边界
包括 模板, 素材, 页面管理, 编辑, 场景设置, 设计师功能等.
其中涉及到编辑组件的功能边界如下
image

编辑器基本框架如下
image

编辑区基本框架如下
qq20170116-3

一个典型的模块及子模块(样式编辑-触发)的代码组织如下
qq20170116-4

后记

从2016年6月开始, 整个项目规模已经达到20w 行代码的规模, 作为易企秀的核心业务, 日 pv 稳定在1亿左右, 是个非常值得骄傲的成绩.

自2017年1月开始, 整个项目就按照当初设想的那样, core+多编辑器实例, 没有太大的变化, 至此笔者有些欣慰, 也有些忧伤.

欣慰的是一年多前的重构架构可以支撑后来一年的迭代, 说明笔者架构的整体思路没有太大问题. 忧伤的也正在此, 笔者知道, 这个架构还远远不够, 还有很多地方可以优化调整. 然而并没有很多大的改动.

当你看到这篇文章时, 笔者已经离开易企秀了, 希望后继者可以提出更加健壮的方案, 助力易企秀再上新台阶.

送给自己的话

在天地之间找一个自己的位置

@xiaoyu2er xiaoyu2er self-assigned this Apr 16, 2018
@xiaoyu2er xiaoyu2er removed their assignment Apr 16, 2018
@10081677wc
Copy link

第一次重构的工作成果确实是非常让人肯定的,
复盘出来对于过去工作的反思也很一针见血,也都是我们今后要做的事情,
这个对于项目结构梳理和小鱼个人心得体会的总结真的是非常有意义和参考价值。

@lookteas
Copy link

您好,请问你们的海报导出功能是如何实现的呢?

@xiaoyu2er
Copy link
Owner Author

@foroso 主要还是后端绘制的 不过目前没有完美的方案... 图片 svg 文字 字体 css 等 都有很多问题
chrome-headless 效果最好 不过不成熟 最后应该都会采用后端渲染的方式

@lookteas
Copy link

@xiaoyu2er 你们现在是用chrome headless来生成图片吗?我在自己的服务器上测试使用的chrome的ppuppeteer工具,通过node跑起来后在客户端请求,同一个url用ab压测30个并发没问题,但是在项目里调用,同时用两部手机请求就会有问题,具体表现为:

  1. 页面没有完全加载完就截图了
  2. 客户端同时发起5个请求过来后,只有第一个或者前两个截图成功,后面几个timeout
  3. 内存资源的消耗很多,平均每个请求占用约80M左右的内存,如果后期有高并发场景可能会让服务器挂掉

测试环境如下:

  • centos7.2 64bit 4核4G
  • node v8.11.3
  • npm 5.6.0
  • ppuppeteer 1.6.0
  • chrome 67.0.3396.99

在体验你们的海报导出功能时,只要1-2秒就好了,但是我这边需要5秒多,而且不稳定。想跟你们取取经,怎么优化提高截图的性能。这个也是困扰我很久了

@xiaoyu2er
Copy link
Owner Author

@foroso 你加我微信吧 zongyanqi

@jlala
Copy link

jlala commented May 25, 2020

@xiaoyu2er 您好 请问易企秀微信网页中是 按照什么比例设计的?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants