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

前端代码规范 #7

Open
yleo77 opened this issue May 10, 2017 · 0 comments
Open

前端代码规范 #7

yleo77 opened this issue May 10, 2017 · 0 comments

Comments

@yleo77
Copy link
Owner

yleo77 commented May 10, 2017

Why?

康威定律中提到一点, 设计系统的组织产生的设计和架构等价于组织间的沟通结构. 类比得说, 一个有章可循的组织所产生的代码也应当是可读性良好的, 反之也成立.

其次, 无规则不成方圆. 同样在一个组织中, 无规范无法成就一份便于团队共享, 交流的代码, 所以有了这篇文档.

这份文档的目的, 并不在于将前端开发中的方方面面都有所提及, 而是会有所侧重, 同时也包含一些最佳化实践, 未来也会不断更新. 另外, 老生常态的一些规则不会从该文中出现或者只是简单略过.

包含四部分: 常规性, HTML, CSSJavascript 相关, Git 相关.

常规性

  • 缩进. 缩进. 缩进. 清晰, 统一的缩进非常重要, 统一为两个空格;
  • 非特殊项目要求情况下, 文件编码统一为 utf-8;
  • 文件末尾添加新空行;
  • 非特殊情况下, 行尾不要留空白符;
  • 代码分块. HTML, CSS中根据实际情况增加空行, Javascript中则可以根据逻辑分块;
  • 熟悉, 熟练你所使用的工具, 也可以不定期回顾下所经常使用的工具软件是否有有用但自己又曾经没有用到的功能, 包括但不限于编辑器, 调试工具等等, 也包括常用快捷键, 想来也能够理解有些公司为什么会将善用快捷键当做一个对候选人的加分项, 后续我将会写一篇关于工具的文章;

以上部分可以借助 EditorConfig 来完成, 在其中找到对应的自己所使用的编辑器插件, 下载安装. 其次, 在项目根目录下配置 .editorconfig 文件即可.

HTML CSS 部分

  • 使用 <!DOCTYPE html> 来声明文档类型(有想过为什么 HTML5 的文档头部声明这么短吗);
  • class, id 属性名需要贴合具体情景, 不允许出现 abc123, x1 类似毫无意义的名称, Javascript 中同样;
  • HTML 所有标签属性小写, 属性值双引号来包裹;
  • link, stylescript 标签都可以省略 type 属性;
  • 使用语义化的标签, 例如知道 divp 的不同场景, 清楚 emstrong 的区别;
  • 当需要借助组件的类名来绑定一些事件时, 这部分类名应当以j-作为前缀, 指代它作为一个 Hook 存在;
  • CSS 中的类名当出现多个单词时, 统一以连字符作为单词拼接, 例如item-btn;
  • 当需要通过链接加载资源时, 例如 script 标签的 src 属性, link 的 href 属性, 以及样式表中的 background-image 的 URL 时, 需要省略掉 http:, 目的是为了让协议自适应。

CSS 相关

  • 请考虑引入一款 CSS 预编译工具, 例如 SASS, LESS或者 PostCSS, 为什么? 因为它具有现代化的开发方式, 将可编程性也带入到了 CSS 中, 能极大帮助我们写出更具模块化的 CSS;
  • 沿着上一条, 避免过度使用这些CSS 预编译工具提供的 nesting Feature;
  • 请考虑采纳 BEM ("Block-Element-Modifier")规范, 引入它的原因在于借助于它, 可以在看到一个元素类名时可以不加思索得清楚它的价值所在;
  • 虽然前端存在最佳实践的教条: 结构表现行为相分离. 但我们也应当在遵守规则的基础上, 知道该什么时候打破规则. 例如在某些情况下可以出现和表现相关的类名, ml10 指代 margin-left: 10px, u-fr 指代 float: right;
  • 和功能性相关的类名应当以u-开头, 例如u-center 居中;
  • 当一个项目涉及到不同的主题表现时, 这部分 class 可以采用 t- 作为前缀;
  • 尽可能, 尽可能不要在 CSS 中出现 id 属性选择符.

以 switch 组件为例

// c-switch 为switch 组件的根节点类名
// c-switch-disabled 指名当前组件处于禁用状态
// c-switch-button 为组件中子元素的类名
<div class="c-switch c-switch-disabled" >
  <span class="c-switch-button"></span>
</div>

Javascript 相关

首先, 是时候要拥抱 ECMAScript 2016(ES7)了, 任何时候将目光朝向未来, 都不会存在大的方向性的错.

  • 选择一份 ESlint 配置, 可以适当做些针对当前团队的调整, 然后坚持遵守这套规则. 目前我们是在eslint-config-airbnb 的基础上所做的调整;
  • 当项目规模到达一定程度后, 请考虑选择一款适合项目及团队的框架, 现阶段可选的一些框架: React, Angular, Vue等, 一个恰到好处的技术框架选型会为你的项目起到不可预估的作用, 甚至在遥远的未来, 也能体现出来;
  • 同框架的选择一样, 工程化自动化相关的工具库也是必不可少的, 尤其是出于当下这个阶段. 未来是否需要, 另一个话题, 暂且不议;
  • Airbnb - Javascript, Google JavaScript Style Guide 这俩份文档应当多看几遍, 前者融合了大量的 ES2015 的最佳实践, 后者更偏重于传统 Javascript 的规范, 也包括了一些 Tips;
  • 行尾使用分号;
  • Javascript 中永远不要相信用户的输入, 不用解释原因了;
  • 即便是多行注释, 也尽可能采用单行注释的方式, 这也是大多数 Editor 默认注释的方式, Why? 其一, 语法层面上来讲, /* */ 的方式不可以嵌套; 其二, 对于经常 grep (或者经常做一些批处理操作代码) 的童鞋来说, 这会为你的后续操作稍微得变得容易一些;

组件相关

  • 每一个组件都有自身的作用域, 有的存在于软件架构底层, 有的属于公用组件, 有的则是业务组件, 也存在部分页面级别的组件, 在编写这些组件时所需要注意的侧重点是存在差异的, 例如生命周期, 性能要求不一样, 可复用程度等等, 底层组件追求极致的性能和代码量的最小化, 而公用(业务)组件可能就要考虑到代码可读性及扩展性. 所以在编写每一类组件时应当注意到这点;
  • 在开发组件的时候, 我更倾向于 TDD 的开发理念, 尽量避免过度设计, 避免大而全过于厚重的组件, 最终发现 80% 的场景只用了组件 20% 的功能, 而组件 80%的功能却大多数情况用不上, 平白无故增加了组件的复杂度及维护成本;
  • 当然了, 组件必须满足开闭原则, 这也是为了应付那20%的场景提供重载/继承, 但此改动只需要反应在业务代码中即可;
  • 设计模式的六大原则上面其实已经隐式提到了两点, 其他的例如里氏替换原则在某些情况下也是需要考虑的;
  • 在设计组件的 HTML 结构, 以及组件不同状态在类名上的表现时, 可按以下格式来建立约束: [Container]-[Element]-[MODIFIER|STATUS], 类似 BEM 规范;
  • 当设计一套组件库时, 组件的类命名可以统一以一个前缀开始, 例如 c- 开始;
  • 在当下盛行组件树开发搭建页面的背景下, 要注意到一点, 不是所有组件在代码中所表现的层级关系也会原封不动体现在 DOM 中. 例如 弹层组件, 它在 DOM 中的层级关系不应该出现在它的父组件之下, 而是在 Body 节点下;
  • 组件和组件之间的通信, 尽量采用事件发布订阅的模式;

Git 相关

  • 每一次的改动提交, 需要在 commit 中将改动的点写清楚, 不要写无意义的字样;
  • 同分支拉取代码时, 请使用 git pull --rebase 的形式;
  • 合并其他分支时, 请在 git merge 的时候使用 --no-ff, 这样做的意义是 merge 的时候会产生一个新的 commit, 合并后的历史可以看出分支信息, 反应软件开发的历史进程;
  • 还是合并相关: 当开发分支commit 提交较为随意时, 在 git merge 该分支时, 可以借助于 --squash 参数重新写 commit 信息, 类似于 svn 分支合并的方式;
  • 分支开发时, 当在开发分支想要合并 Master 分支的更新时, 请使用 git rebase master 的方式, 会得到一个线性的提交记录, 如果不小心使用了 git merge master 的方式, 会将开发分支的 commit 历史变得混乱, 试想一下, 先把 master merge 到分支上, 未来也是会要把该分支 merge 到 master 上, 结果是不是会很糟糕呢;

Vue 相关

  • API 以及 Guide 会帮你回答绝大多数在使用 Vue 中的问题, 同时 Vue.js devtools 可以帮你发现很多问题;
  • 可以多关注下项目中所选择的框架生态发展;
  • Vue 的单文件组件系统设计确实非常好用, 你应当充分发挥这一便利. 进一步说, 单文件系统中的 template 标签, script 标签以及 style 标签中的内容要统一从缩进两个空格开始;
  • 通信在程序设计中是一件稀松平常的事情, 在基于 Vue 的组件系统中组件也会存在经常通信的情况, 有父和子的通讯, 有平级别的组件通讯, 也有八杆子打不着关系的俩个组件存在某种通信的case, 每种情况都有不同的推荐, 和数据流的变更相关, 有时候可以借助 Vuex, 考虑松耦合时可以借助 messagebus 来处理事件通信, 父和子的情况则可以优先考虑通过 props 的形式, 想要一个 messagebus 在 vue 中也非常容易, 只需要一个实例化好的 vue 对象即可, 例如:
const messagebus = new Vue();
// 监听事件
messagebus.$on('button.clicked', () => { ... });
// 触发事件
messagebus.$emit('button.clicked');

写在最后

当你看完全文, 可能会发现, 本篇文章并没有全文都着笔于代码规范上, 在这之外, 也添加了很多个人认为的最佳实践与见解.

在程序优化中有一条法则是

永远不要优化代码,直到你真正需要

对于程序的设计也是依然如此, 保证不要引入不必要的复杂.

资料

持续更新中...

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

No branches or pull requests

1 participant