速来报名!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:2610106

评论

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

蓝易云 - springboot配置静态资源访问

百度搜索:蓝易云

CSS JavaScript 运维 Spring Boot js

蓝易云 - Nginx查找耗时的接口

百度搜索:蓝易云

nginx 云计算 运维 服务器 云服务器

蓝易云 - centos服务器a.sh内如何 在指令中自动加入当前时间?

百度搜索:蓝易云

云计算 centos 运维 服务器 云服务器

内存分配器的性能优化

不卡科技

Go 性能优化 流媒体开发 内存池

首批!华为云盘古研发大模型通过代码大模型评估,获当前最高等级

华为云开发者联盟

人工智能 华为云 华为云开发者联盟 华为云盘古大模型 企业号2024年6月PK榜

探索未来:区块链技术的革新之旅

dappweb

defi 元宇宙开发 区块链开发

30天拿下Rust之图形编程

希望睿智

rust 图形软件

Partisia Blockchain的MOCCA方案,如何成为资产托管最优解?

股市老人

华为云CodeArts API:API管理一体化平台 5月新特性上线啦!

华为云PaaS服务小智

软件开发 API 华为云

喜讯!云起无垠入选《2024中国AI大模型产业图谱1.0版》

云起无垠

30天拿下Rust之高级类型

希望睿智

rust 类型

深入浅出: XML HttpRequest 入门指南

秃头小帅oi

大模型产品化,不过是三支舞

脑极体

AI

AI日报|仅三个月就下架?微软GPT Builder出局AI竞争赛;马斯克将撤回对奥特曼的诉讼

可信AI进展

快速识别你家的猫猫狗狗,教你用ModelBox开发AI萌宠应用

华为云开发者联盟

人工智能 华为云 华为云ModelArts 华为云开发者联盟 企业号2024年6月PK榜

一文读懂Partisia Blockchain 的MOCCA方案:资产托管的最优解

西柚子

数智领航 云启未来|华为云618营销季全面启动

YG科技

Partisia Blockchain的MOCCA方案,资产托管领域的全新范式

股市老人

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