阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

如何打造公司级公共前端团队

  • 2016-08-07
  • 本文字数:6449 字

    阅读完需:约 21 分钟

本文为 8 月 4 日,『前端之巅』群『滴滴公共 FE 团队技术开放月』第一场分享活动总结整理而成,转载请注明来自『前端之巅』公众号。

张耀春,滴滴公共前端团队负责人,2009 年接触前端,5 年多博客撰写经历。国内较早接触 Node.js,2013 年开始应用 React、Angular、Polymer 到业务组件中,2014 年曾参与翻译《Professional Node.js》一书。最近探索和应用的新技术:rollup、riot、vue 等,领导团队一起钻研新技术的书籍预计于今年 8 月底出版。

作为公司级的公共前端团队,应该如何对团队进行定位,在实践过程中应注意哪些问题,如何打造这样的团队?本文对滴滴公共前端团队的实践进行了总结,希望能带给读者一些启发。

一、团队定位

1. 团队情况

滴滴公共前端(FE)团队现在有十多个小伙伴,男女比例为 1: 1

主要包含以下几大职能方向:

  • H5 运营富交互动画案例方向
  • WebApp 和端交互方向
  • 统一支付方向
  • 公司通用类 MIS 业务前端研发和服务配置化方向
  • 数据可视化和地图方向
  • 公司级组件库建设方向
  • 统一 Nodejs 服务(API、微服务、MIS 等)
  • 跨端体验方向
  • 新技术孵化方向

团队职责:

  • 全局:站得角度更高
  • 公共:抽象得更通用性
  • 孵化:新技术在新业务应用落地

2. 团队实践

作为公司级公共前端团队,滴滴公共 FE 团队的实践主要从以下几方面进行:

(1) 全局类:①公司统一权限登录移动化和 PC 改版;②移动端用户统一登录 SDK。

(2)可视化方向:滴滴国内央视曝光 10 多次春运迁徙可视化。

(3) 组件化方向:公司级组件库——魔方。

(4)通用服务:①TMS 运营和模板平台;②NPM Private。

(5)用户类:①微信等渠道内嵌的 WebApp 首页;②端内钱包支付等统一界面相关;③最近上线的安全行程分享;④H5 前端服务化的项目:如滴滴捐献里程活动。

3. 团队努力方向

(1)努力成为公司业务线上的前端开发人员所信赖的伙伴、公司业务强有力支撑的前端技术团队。
(2)对前端业内有一定贡献的团队。

二、团队的实践和产出

滴滴公共 FE 团队做的实践还是很多的,现列举几个比较重大且应用度广的实践。

1. 公司级组件库:魔方

(1)痛点

魔方主要为了解决的痛点是:每一个系统 UI、交互规范、组件技术都不一样,复用性低,依赖第三方开源但技术支持不到位,遇到问题没人服务。

(2)途径

为了解决问题,我们通过以下途径,综合考虑,开发了魔方。

  • 与公司设计团队和交互团队沟通,至上而下,统一 UI 视觉规范、交互规范。
  • 与业务团队沟通应用技术,先优先大概率群体。
  • 提供官网和 24 小时双 VIP 技术支持服务。
  • 不光解决前端、放在更大的视角里面:客户端组件、视觉等。

(3)展示

以下是魔方的截图,可以通过这些截图,看到魔方所提供的主要服务。

(4)技术

魔方所用到的技术,包括以下几点:

  • PC 端:Angular+sass+WebPack
  • H5 端:
    • 第一版:zepto+dmu(优化版的 gmu)+styl+handlebars+WebPack
    • 第二版:Vue+WebPack
  • 前端规范:
    • jsbridge:ES6+(WebPack||rollup)+babel
    • 唤起 App: 统一的中间页服务 +iframe 请求 schema
  • 数据可视化:Canvas 类库封装 + 统一 theme+ 上层配置化
  • 地图可视化:底层适配高德和腾讯,采用动态打包 (WebPack+require.ensure)

(5)魔方 PC 端构建流程

由于 PC 我们全部依托 Angular 指令来编写,在 WebPack 采用了ngtemplate-loader

不同环境两套配置文件:

复制代码
webpack.config.js // 开发环境
webpack.min.js // 生产环境打包

区别:

复制代码
//webpack.min.js
output: {
path: __dirname + '/dist/mofang-widget/' + version,
filename: '[name].min.js',
library: 'mofang',
libraryTarget: 'umd'
},

我们打包之后的目录:

复制代码
dist/mofang-widget/0.1.1/mofang-widget.min.js

如何配置第三方依赖:

复制代码
resolve: {
root: path.join(__dirname, 'src'),
alias: {
components: path.join(__dirname, 'src', 'components'),
vendor_a: path.join(__dirname, 'src', 'vendor'),
ui_bootstrap_a: path.join(__dirname, 'src', 'vendor', 'angular-ui-bootstrap'),
ui_select_a: path.join(__dirname, 'src', 'vendor', 'angular-ui-select'),
resource_a: path.join(__dirname, 'src', 'vendor', 'angular-resource'),
sanitize_a: path.join(__dirname, 'src', 'vendor', 'angular-sanitize')
}
}

如何处理 directory 里面的 template:

复制代码
// 目录结构
components
didi-list
didi-list.html
didi-list.js
复制代码
// bn-list.js
var templateListUrl = require('./bn-list.html');
// 指令代码:
{
templateUrl: templateListUrl
}
复制代码
module: {
loaders: [
{
test: /\.html$/,
loader: 'ngtemplate!html'
}
]
}

如何按版本发布:

整体我们依赖 pkg.json 的 version:

复制代码
var version = require('./package.json').version;
// 方案一:
plugins: [
new webpack.DefinePlugin({
__VERSION__: JSON.stringify(version)
})
]
// 方案二:
callbackLoader: {
getVersion: function () {
return "'" + version + "'";
}
}

关于 iOS 9 Safari iframe src with scheme not working:

具体可以参阅: http://stackoverflow.com/questions/31891777/ios-9-safari-iframe-src-with-custom-url-scheme-not-working

WebPack 动态加载:

复制代码
require.ensure([], function (require) {
var qqmap = require('./qq/qqmap');
callback && callback(qqmap);
}, 'qqmap');
require.ensure([], function (require) {
var alimap = require('./ali/alimap');
callback && callback(alimap);
}, 'alimap');

2. 公司级统一运营服务:TMS

(1)痛点

TMS 为了解决的痛点如下:

  • 前端修改上线尤为频繁、如何解决资源推送 CDN、达到快速、高效、智能的上线流程
    运营类 H5 zip 上传能否支持
  • 如何快速 Mock 一个线上 API 配置
  • 如何快速生成一个短链、二维码等
  • 有一个图片,能不能快速生成一个 H5 页面

(2)途径

我们采取了以下途径:

  • 搭建一个稳定、可扩展、权限可控、可监控的服务平台
  • 支持多元化的服务调用:API 调用和用户界面操作
  • 和公司的基础架构及运维合作共赢

(3)技术

我们采用更定制化的 Nodejs 服务框架(从 Sailsjs 参考了很多)+mongo+pm2,结合公司发布系统、定制日志监控和脚本化运维规范。

(4)架构图

详细的架构如下图所示。

(点击放大图像)

(5)遇到的技术问题

①如何灵活地进行线上线下配置

我们的 DNode 系统里面,默认支持 2 个配置文件。

复制代码
config/env/dev.js
config/env/prod.js
复制代码
// config/env/dev.js
{
port: 1234
}
// config/env/prod.js
{
port: 8000
}

启动服务的时候,控制参数:

默认走的是 dev 的所有配置。

复制代码
dnode app.js --prod

这样默认就执行了所有 prod 的配置参数。

②脚本化运维 DNode 服务:

整体我们还是依托公司的发布系统,设置后置脚本来部署和安装部分依赖。

复制代码
build.sh --- 部分安装,配置等
control.sh --- 提供一些方法来控制服务,启动 pm2 的参数和日志路径等
* `./control.sh start`:启动服务,如果服务已经启动会报错。
* `./control.sh restart`:重启服务,要求服务已经启动才能正确执行。
* `./control.sh reload`:优雅重启服务,要求服务已经启动才能正确执行。
* `./control.sh stop`:停止服务

③日志监控:

设置固定的日志,依托公司统一日志监控,设置拉取策略和一些采集匹配规则。

④如何处理不同类型的文件上传

在 DNode 里面我们所有的请求都会安装配置的 middleware 数组顺序,进行流转。这样的优势在于,我们可以在一开始设置一些 requestTimer 的监控 middleware。

首先我们检查 request 头是:

复制代码
if (req.is('multipart/form-data')) {
{1}
}

然后我们会通过formidable的 2 个方法:

复制代码
var formObj = new formidable.IncomingForm({
uploadDir: uploadPath,
keepExtensions: true,
multiples: false
});
formObj.parse(req, function(err, fields, files) {
// 这里面我们可以 check file.type 来对不同类型的文件进行不一样的处理:
// 比如 css 文件:
if (files.file.type == 'text/css') {
minCssCode = new CleanCss().minify(cssCode).styles;
}
// 比如 js 文件:
if (files.file.type == 'text/javascript') {
minJsCode = UglifyJS.minify(jsCode, {fromString: true}).code;
}
// 比如 zip 文件:
if (files.file.type == 'application/zip' || files.file.type == 'application/octet-stream') {
}
}

⑤如何限制体积:

我们这边采用的是skipper在 bodyParser 的 middleware 里面做了一次过滤。

3. MIS 服务化、配置化、GUI 化以及前后端分类

(1)痛点

  • 随着业务发展,随之配套的各种 MIS 运营、管控、数据可视化系统,业务需求紧急、前端同学人力投入大、联调效率低。
  • 前端同学依赖的构建工具和编辑器各异,有时候初始化开发环境都需要 1~2 天。

(2)途径:

  • 与后端同学沟通数据接口规范、推行 RESTFul API、沉淀业务组件库。
  • 联调方式以 Wiki 为准、统一出处。
  • 前后端独立分开部署、后端 API 通过跨域或者反向代理等方式通信。
  • 成熟的 Nodejs 服务化:脚手架、配置化、生产测试环境隔离命令脚本化。
  • 微服务化:权限、登录、邮件等微服务化或者 SDK 化。

(3)技术

Nodejs+ 数据存储 + 各种配置系统 + 脚本。

4. WebApp 首页公共化

(1)痛点

滴滴早期 WebApp 首页是由业务线同学维护,与业务线有一定程度耦合,新业务线接入相对比较困难,会暂用业务线同学本身已有的开发任务。

(2)途径

  • 与业务线研发和产品沟通、阅读代码,梳理逻辑和需求。
  • 设计一套与业务线完全解耦的前端框架,业务线通过动态加载 JS 实现自身的业务逻辑。框架定义了业务线的生命周期,提供公共接口、通用组件库和统一样式供业务线调用,通过事件机制和业务线通讯。业务线可独立自主上线迭代,而不用公共的参与。
  • 提供详细的接入 wiki 和 24 小时 VIP 技术支持服务。

(3)技术

  • scrat 完成打包 + 构建。
  • gmu 实现组件化。
  • 前端模板 handlebar。
  • combo 服务。

5. H5 统一登录 SDK

(1)痛点

滴滴早期的登录每个业务线都会做一套,有开发成本。不利于账号部门收敛和管理各业务线账号,不利于做一些账号安全和组件升级;登录没有打通,新业务线或运营活动接入登录成本高。

(2)途径

  • 账号与账号部门合作,输出公司级别的 H5 统一登录 SDK,统一收敛和管理业务线账号,统一升级。
  • 采用 Facebook 的统一登录方案,登录状态 ticket 缓存在 passport 域名下,打通滴滴各个域名的登录态。
  • 业务线和运营活动页面接入只需引入一个 JS,登录 SDK 提供 login、logout、isLogin 等接口,使用简单方便。
  • 提供详细的接入 wiki 和 24 小时 VIP 技术支持服务。

(3)展示

(4)技术

  • 原生 JS,没有任何依赖。
  • WebPack 打包 + 版本管理。

6. Npm Private

(1)痛点

前端项目越来越多,内部产出的工具包也比较多,如何自建一个私有库。

(2)途径

  • 调研市面的解决方案
  • 定制化滴滴特色的解决方案

(3)技术

  • 参考更多 sinopia 的一些优势、配置化和全局命令部署
  • 申请存储容量稳定的机器作为部署机器
  • 完备的官网和使用方法和场景问题

三、如何打造公司级公共前端团队

这个问题其实我每天都在思考,好像一直没有太明确的答案,这里也只是分享一些我个人的见解:

  • 技术氛围和培养机制
  • 鼓励和提倡技术革新
  • 沉淀和解决业务痛点
  • 有规划、有目标、有理想
  • 客服意识要强

下面我从几个方面具体来谈一谈。

1. 理想中的公共团队

团队永远和人有关系,下面我从几个简单的维度,通过我对几个游戏的理解来分享一下我认为公共团队的人所需要的气质。

(1)“飙车”

敢于超越,专业性要求高:赛车手和我们一般的开车的同学相比:更专业、对车子的熟悉度更高、追求超越和不愿意被超越。我很多时候推荐团建都是去玩室内卡丁车,而且每次都发现:有一些同学愿意最后和一些跑圈快的一组再比一轮,即使最后,那可能也是其他圈里面最快的。

(2)乐高拼图

能够沉浸在技术里面,去思考问题,最终产出:乐高一般有几千块零散的拼图、需要沉下心来、而且在脑海中大概有一个架子,不断地去尝试和调整,最终完成一个作品时候,你会很自豪。

(3)潜水

敢于挑战自己惧怕的东西,克服困难,战胜自己:潜水是我开始最惧怕的一项运动,很早前我不会游泳,但我又渴望翱翔大海,在一段比较长的震痛期后,我完成了浮浅和深浅,看到了很多常人看不到的美丽景色:大海龟、大鲸鲨、暴风鱼群等。

(4)写作和分享

沟通和沉淀才能让知识更记忆深刻:我自己喜欢翻译和写一写技术总结的文章,已经成为生活中一个不可或缺的习惯。然后再分享出来,得到一些批评和反馈。

2. Leader 个人水平的提高

(1)制定计划

作为团队负责人,其实我的压力还是比较大的,除了满足业务需求外,你更多还需要告诉团队方向在哪里、我们的计划是否是可以落地的。所以我会制定一些计划来提高个人的水平。

  • 一般我们会做半年计划:包含长远目标和最近目标。
  • 管理上:参加了公司第一期的黄埔军校 - DMW 管理培训以及很多管理相关课程学习。
  • 技术上:一般我自己会保持比较高的阅读范围和一些国内外优秀的技术群,参加一些技术活动,例如以下几点。
    • 每月一本的技术书籍。
    • 定期向一些比较资深的前辈取取经。
    • 参加一些业内比较知名的大会,比如最近的 Qcon。
    • 长期保持技术文章沉淀总结分享的习惯。

(2)如何更合理地提供解决方案?

我自身也折腾过各种机器和环境部署、数据库,也接触过后端和安卓开发,在研究跨端体验的时候,花了两个月看了 iOS 相关的基础书籍和代码。

很多时候解决方案的合理性和全局观,不只是你熟悉业务就可以了,我更倾向让团队的很多同学熟悉前端独立部署、如何和不同的端交互以及他们内部相关的技术组成。而且大部分时候不敢于技术革新的一个很大原因:不了解、不熟悉、没把握。

(3)如何高效地管理写代码和管理时间的分工?

很多时候时间确实是不够用的,而且有时候会参加很多会议和培训等。我管理时间一般的方式如下:

  • 工具化管理:TODO LIST 的软件 + 一些提醒。
  • 技术获取:订阅 list 和 pocket 软件收藏。

3. 团队管理

(1)对内外的沟通

  • 很多时候,我都会去找业务线的前端小伙伴包含一些 Leader 同学去交流沟通,看看他们的反馈和一些问题是否有公共的痛点。
  • 组内定期沟通:保持每周部分同学的沟通、每周全组周会。

(2)代码 review 和风格一致性

  • 很多人用过 jira、我推荐 Phabricator。
  • ESlint 等工具的工程化配置。
  • 脚手架的统一但不失多元化。

(3)团队学习和应用的技术方向

团队技术的提高离不开学习和应用新技术,最近新技术的落地有以下几点:

  • Vue、riot H5 组件化推广
  • 打包工具 WebPack --> rollup 迁移
  • 代码化:babel + ES6
  • 更多从业务中抽象的微服务
  • 更多脚本化运维推广
  • 编译器相关探索
  • 跨端技术解决方案

(4)创造活跃的技术氛围

在很多时候,永远需要一个带头人跑的快一点,积极一点,在技术上鼓励创新和不断打磨沉淀优化,鼓励团队的小伙伴通过一些工具和技术手段来解决一些重复性的事情。

除了利用合理、稳定、高效的技术解决方案来服务日常的业务支撑外,考虑到前端技术的日新月异,我们也沉淀和创造一个统一的技术氛围:

  • 公司比较早创办的 DDFE 的前端技术群
  • DDFE 前端技术微信公众号
  • DDFE Weekly
  • DDFE Github blog

四、致谢

公共 FE 团队在任何一个大公司都离不开业务线小伙伴的支持和厚爱、领导的认可和关注。

滴滴公共 FE 团队的发展,离不开所有给予我们帮助和信任的朋友,也离不开团队每一位亲爱的小伙伴的努力工作。

一路同行,只因为有你们:huangyi、wangjing、wangjin、suwei、shumei、xiaoqi、yanfen、miaodian、cuijing、yufei、huan 总。

『前端之巅』群『滴滴公共 FE 团队技术开放月』分享活动预告:第二期:WebApp 实践经验分享;第三期:公司级组件库以及 MIS 系统的技术实践分享。


感谢韩婷对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-08-07 17:269870

评论

发布
暂无评论
发现更多内容

2021 China DevOpsDays演讲实录

homber

DevOps DevOpsDays 签约计划第二季

少儿春晚表演

Tiger

28天写作

一文讲透数仓临时表的用法

华为云开发者联盟

数据库 sql Local GaussDB(DWS) 临时表

恒源云(GPUSHARE)_云GPU服务器如何使用PyCharm?

恒源云

深度学习 gpu 算力加速

服务端质量保证体系(一) 全流程规范管理

homber

服务端 流程 质量保证 签约计划第二季

Linux一学就会之Centos8软件包的管理和安装之yum管理软件包

学神来啦

Linux centos 运维 rpm yum

使用Harbor作为Rainbond默认容器镜像仓库,扩展Rainbond镜像管理能力

北京好雨科技有限公司

【讲坛实录】知识图谱的探索与应用

星环科技

知识图谱

【分布式技术专题】「OSS中间件系列」Minio的Server端服务的架构和实战搭建

洛神灬殇

OSS Minio Minio 集群 12月日更 FS

Go语言学习查缺补漏ing Day3

恒生LIGHT云社区

Go 编程语言

QA进阶成长感悟录

homber

成长 内容合集 签约计划第二季

开源机器学习数据库OpenMLDB贡献者计划全面启动

第四范式开发者社区

第四范式 开源社区 OpenMLDB 机器学习数据库 贡献者

服务端质量保证体系(二) 流水线标准化建设

homber

服务端 CI/CD 流程 质量保证 签约计划第二季

企业如何做好员工安全意识提升

腾讯安全云鼎实验室

Redis 核心知识点归纳总结,从根上理解 Redis

码哥字节

redis Redis 核心技术与实战 签约计划第二季

服务端质量保证体系(三) CI原子能力建设

homber

ci 服务端 质量保证 签约计划第二季

大数据开发之数据读取—Pandas vs Spark

@零度

大数据 spark pandas

Redis 很强,不懂使用规范就糟蹋了

码哥字节

redis Redis开发规范 签约计划第二季

Apache ShenYu源码阅读系列-注册中心实现原理之Http注册

子夜2104

基于HTML、CSS和JS的年龄计算器

海拥(haiyong.site)

html 大前端 28天写作 签约计划第二季 12月日更

「Oracle」Oracle 数据库备份还原

恒生LIGHT云社区

数据库 oracle

星环科技 TDH8.1.0:全新升级为用户带来极致体验

星环科技

大数据

换个角度思考勒索攻击事件

华为云开发者联盟

漏洞 勒索 攻击 安全检测 蜜罐检测

为什么要做团建TB?(6/28)

赵新龙

28天写作

基于HTML、CSS、JS的小游戏/工具制作过程及完整源码

海拥(haiyong.site)

28天写作 内容合集 签约计划第二季 12月日更 技术专题合集

云原生时代的"应用级"多云管理

北京好雨科技有限公司

云计算 Kubernetes 容器 多云管理

编程谜题:提升你解决问题的训练场

华为云开发者联盟

Python 编程 编程语言 代码 编程谜题

会用泛型,但你知道什么是泛型的类型擦除吗?

码农参上

Java泛型 签约计划第二季

和合共赢,DataPipeline与麒麟软件完成产品兼容性互认证

DataPipeline数见科技

中间件 数据库中间件

Python代码阅读(第67篇):获取列表中的去重后的元素

Felix

Python 编程 列表 阅读代码 Python初学者

春松客服入驻Rainbond开源应用商店

北京好雨科技有限公司

如何打造公司级公共前端团队_语言 & 开发_张耀春_InfoQ精选文章