Giter Club home page Giter Club logo

efe's Introduction

EFE

简介

百度 EFE(Excellent FrontEnd) 技术体系,前身是 ECOM前端团队,后经过技术的发展,逐渐形成一套完善的前端技术体系。

EFE 技术体系现由多个遵循该技术体系的前端团队所组成。E(Excellent) 代表我们追求卓越的技术态度。

技术委员会

EFE 技术委员会简称 EFE-TC ,由方向技术负责人团队技术负责人T7+工程师组成,由 EFE 主席 带领。

EFE-TC 的主要职责是技术方向把握,在技术上决定 EFE 体系做什么、怎么做、不做什么。

技术方向

EFE技术体系划分了五个技术方向。下面列表中,@后面的人为方向负责人。

  • Data Visualization @pissang
  • Interface @Justineo
  • Mobile @firede
  • Platform @leeight
  • RIA @otakustay

技术价值观与要求

精细化

  • 在技术和方案设计上深思熟虑。应用面越广的技术产品,错误的设计与实现带来的危害和影响面越大。
  • 代码质量需要严苛要求,极端情况下因为项目排期紧张导致需要妥协,也应该给出改进时间和计划并严格实施,不得二次拖延。
  • 对于问题要明确“做什么(What)”、“为什么(Why)”、“怎么做(How)”,不得以个人经验或者喜好进行技术判断。
  • 设计、方案、开发过程需要有记录,便于追溯。
  • 无GUI类产品,测试用例需要覆盖完全。有GUI类产品可自由把握。
  • 技术产品不允许为了抢占地盘,快速挖坑粗糙实现,然后在不成熟的时候大范围铺开应用。
  • 技术产品需要有完善的文档。
  • 技术产品需要有使用样例。

开源

业务无关的纯技术产品,必须开源,并且代码托管在github上。包括库、框架、工具等。

纯技术产品的设计、方案选型、开发过程运作需要在github issue上公开、有记录。通过实时聊天工具或邮件达成的技术方案等结论,也需要事后在github issue上记录存档。问题、改进建议等用户反馈,也需要通过github issue进行。

持续性

开源技术产品的维护要有持续性,不得出现找不到人、无人响应的现象。即使技术产品本身已经很完善,github issue中的问题和提议维护者需要持续回答。

当维护者离职时,如果有兴趣可以继续维护,否则需要交接给其他有兴趣的人。

代码符合规范

fecs 工具可以对 JavaScript/HTML/CSS 代码进行检查。

采用模块化方式管理代码

为了便于代码逻辑划分、依赖管理、系统分析与优化,在项目开发中必须使用模块化的方式,各种资源引用不得手工维护。允许使用的模块化方式有以下两种:

  1. 通过 AMD 进行模块化开发。使用该方式需要遵循模块规范
  2. 通过 CommonJS Module 的方式开发,通过相应工具在开发时与构建时进行前端的运行包装。使用该方式,必须将 CommonJS 模块包装成 AMD。

对同类功能,有复用价值的代码集,通过 package 进行封装

通常在前端项目中,库、框架、多业务共用的公共模块适合通过 package 进行封装。对 package 进行封装需要遵守包结构规范,该规范在 CommonJS Package 下做了一些细化。

package 可以通过 private npmbower 发布

项目的前端部分,目录结构符合规范

  1. 一个只包含前端代码的项目,整个项目必须符合项目目录结构规范
  2. 如果混合PHP、NodeJS等服务端代码的项目,项目的前端部分需要独立单独的目录,该目录的内部结构必须符合项目目录结构规范

通过同一个blog进行技术输出

对外的技术输出必须统一使用 EFE Site。更新方法和内容要求参见 ecomfe.github.io repos

加入EFE

加入 EFE 的前端团队,需要符合上述技术价值观和遵循上述要求。

加入方法

  1. 联系 EFE 主席,要求加入。可说明加入理由和技术规划或方向。
  2. EFE 主席在 EFE-TC 发起讨论和投票。反对票少于 1/3 时,允许加入。

权利

  1. 获得至少一个加入 EFE-TC 的名额。
  2. 标准和规范发起增补和完善。
  3. 影响 EFE 的技术发展方向。
  4. 团队所有成员都可以在 efe.baidu.com 上增加内容,包括 Blog 文章和技术产品。
  5. 以 EFE 的名义进行符合 EFE 价值观与要求的技术的宣传。

义务

  1. 遵循上述技术价值观与要求
  2. 严格遵守标准和规范

常见问题

EFE 的官方 repos 为啥在 ecomfe org 下?

  1. EFE 从 ECOMFE团队(现已解散)发展而来,之前的开源项目很多是放在这的,迁移成本太高。
  2. github上,EFE已经被别人先注册了。

团队的开源项目是否必须要放在 ecomfe org 下?

EFE 只要求技术项目必须开源,托管在 github 上,但并不要求必须放在 ecomfe org 下。每个团队都可以有自己的 org,存放自己团队的开源项目。

但是,下面两项资源需要共同维护,不得在自己团队的 org下单独建立:

  1. 标准与规范。需要统一使用EFE spec
  2. Blog.需要统一维护EFE blog

efe's People

Contributors

erik168 avatar firede avatar otakustay avatar pissang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

efe's Issues

EFE-TC 2016 会议记录 Draft

以下为会议记录,结论需由各方向负责人单开issue细化、跟进、落实。

技术方向调整

  • 增加WebPage方向
  • RIA方向调整为WebApp方向

议题

解决方案分开与融合的边界

用户系统与业务系统

  • 增加WebPage方向,进行用户系统的构建方案、CDN方案等基础设施建设
  • 和业务系统不公用组件,部分基础设施可复用(如概念等),需重点评估运行环境的差异

移动与PC方向

  • 移动端使用ES6需调研体积上是否能接受
  • React Native在预期明确的场景可以使用 @鹏宇

Interface方向

  • CSS loader以JS为入口
  • Font icon或SVG按项目需求选择?
  • CSS package管理功能

Node在线服务

  • 与orp谈解决方案分层的可能性 @errorrik
  • orp与JPaaS结合的可能性 @errorrik

从工具化到服务化

  • 编译集群的支持问题(机器的问题)
  • UT、接口的测试平台?持续集成方案?
  • 前端开发/交付容器化?

客户端

  • 整体方案的整理
  • 截屏、录屏、版本升级等通用功能

面向RD的解决方案

  • 给RD提供前端开发环境
  • 文档,最佳实践的完善

实践社区技术栈

  • 实践与积累的方式
  • 产品线技术选型showcase

RIA问题

  • 向下兼容的粒度,遵循semver
  • Routing与UI分离
  • 松依赖,入口整合
  • ...

Platform问题

  • 构建速度太慢,增量编译
  • build对非JS模块没有较好的处理方式
  • processor要抽出来,build和webserver通用部分要合
  • 区分es5, es6
  • ...

其他

  • 开源技术产品的规范 @firede

一种更纯粹的组件实现方式

还请 @errorrik 过目……


Inspired by react, redux, mvvm and many many more...

介绍

一个组件分为“数据”和“事件”两部分,其中数据进一步分为“数据的声明”、“数据的初始值”和“当前数据”

class Component {
    data,
    dataTypes,
    initialData,
    events
}

到这一步为止基本就是一个React和Vue的合体,区别在于下面。

当组件实际渲染后,触发了一定事件时,会调用事件对应的函数,而这个函数是一个“纯函数”,它接受当前的数据,返回新的数据(Redux的reducer):

let reduce = async (currentData, fire, ...eventArgs) => newData;

你说为什么偏偏是currentDatafire两个参数,因为一个组件的输入是数据,输出是事件,所以这相当于inputoutput

实际的流程是触发事件后,用函数计算出新的数据,把新的数据补丁到原有的数据上,进一步触发视图的更新。

优势

不需要Model的实现

永别了,我自己写的emc……

更加纯粹

所有的事件处理函数都是纯函数,本身是可单独测着玩的。

更强制地引入Immutable

我不相再赘述Immutable的作用和优势……反正我认为在我的diffy-update的支持下更新Immutable数据并不是那么困难的事。

对绑定同样友好

绑定是发生在data之下的,并不受任何影响,且因为一个reduce返回的新对象可能包含多个属性的修改,相当于默认实现了一定程度上change的合并,不必在纠结所谓的合并不合并的问题。

可组合复用

这点很重要。

在这个模式下,一个组件其实被明确地分为几个部分,除了“当前数据”之外,其它部分其实可以灵活的组合,我的一个组件可以写成这样:

import {set} from 'diffy-update';
import {Types} from 'san-ui/Types';

export let events = {
    async click(data, fire) {
        fire('click');
    }

    async duplicate(data) {
        return set(data, 'text', data.text.repeat(2));
    }
};

export let dataTypes = {
    text: Types.string
};

export let initialData = {
    text: ''
};

export default class Label {
    events = events;
    dataTypes = dataTypes;
    initialData = initialData;
}

此后我有了自己的一个组件,虽然长得不一样,也有一堆逻辑不一样,明显地不能继承Label,但正好也要个duplicate的功能,正好点了以后要触发click事件,那就方便了:

import {events} from 'Label';

export default class BeautifulLady {
    events = events;
    dataTypes...
    initialData...
}

当然我们可以更细化,让Label变成3个文件:

// label/events.js
import {set} from 'diffy-update';

export let click = async (data, fire) => fire('click');

export let duplicate = async data => set(data, 'text', data.text.repeat(2));


// label/Label.js
import * as events from './events';

export default class Label {
    events = events;
    dataTypes...
    initialData...    
}

这样我可以只复用其中的duplicate部分,而不需要click,相当方便。

当然我们更多的时候,面对的是数据结构不尽可同,但是逻辑相似的情况,这时就可以上高阶函数:

// transformer.js
export let withMapping = mapping => reduce => async (data, fire) => {
    let newData = await reduce(data, fire);
    let mappedData = Object.entries(newData).reduce(
        (result, [key, value]) => {
            let mappedKey = mapping[key] || key;
            return {[mappedKey]: value, ...result};
        },
        {}
    );
};

// BeautifulLady.js
import {withMapping} from 'transformer';
import {duplicate} from 'label/events';

let events = {
    duplicate: withMapping({text: name})(duplicate)
};

export default class BeautifulLady {
    events = events;
    dataTypes...
    initialData...
}

以上仅仅是说明了events这一块如何通过组合来达到比继承更强大的复用性,其实dataTypesinitialData同样可以复用,但考虑到这只是普通的数据结构,并不特别适合去复用,就不在此展示。

劣势

很显然,这需要一定的技术素养才能掌握。

过强的复用性可能让代码的组织变乱,各个组件间对events的依赖显得比较奇怪。

events本身是组件内部的一种实现,这样放出去给人复用并不适合大部分情况,通常只是在共享逻辑但定制外观的时候才有用。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.