前言
我们是一群热爱编程的代码农,但我们不是代码奴!
我们为写的代码负责,对代码素质有要求,由代码风格开始,测试,编写技术文档,一丝不苟!
如果看到代码中有不符合以下规范的地方,请及时修改更正,如果你发现了不修正,和咸 🐟有什么区别。
以下规范由团队成员共同维护制定,请务必遵循这些规则,也请参与进来共同维护规范。如果发现规范有不合适的地方,请comment后修正规范,并让大家知道。
代码风格
我们的代码风格:eslint-config-aftership
所有人遵循一套代码风格。
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
文件结构组织
每个项目都应该维护一份项目文件结构,当结构发生变化时请及时更新。希望所有人都遵循该结构的组织逻辑,也避免不同参与人员带来项目结构混乱。可以用tree
来辅助生成。
导入与导出
-
尽量避免使用
default
来进行导出,这样对tree-shking不太友好。 -
通常在React组件的设计中,一个文件只对应一个组件,并使用 default 导出。
-
导入之后不用的,请删掉它。
// Wrong: useEffect, useCallback unused. import React, {useState, useEffect, useCallback} from 'React'; export default function Com(){ const [info, setInfo] = useState(null); return <></> }
代码模式
-
避免循环依赖
不可以将循环依赖引入我们的代码结构。当你遇到循环依赖时,随时与其他开发人员讨论如何避免这种情况。这种情况一定是可以被避免的,虽然基本上就是将这两个文件共同依赖的部分放入第三个文件。
-
函数式暴露
避免将自身的内部变量直接暴露给其他的模块/类。当你需要更改一个具有暴露内部变量的组件或者函数时,必须考虑所有相关组件的所有代码。
// Unsuitable export let currentRunningConversion = null; export function startInactiveTabConversion(conversionSetting) { // ...other code currentRunningConversion = conversionSetting; } export function stopInactiveTabConversion(originalTitle) { // ...other code return currentRunningConversion; } // Correct let currentRunningConversion = null; export function get_CRC() { return currentRunningConversion; } export function set_CRC(conversionSetting) { currentRunningConversion = conversionSetting; }
-
请把异常处理和兜底作为编码习惯。
HTML & DOM
- 尽量减少dom层级及数量,善用css伪类。
JS Coding
变量
-
不要使用关键字或者是浏览器内置对象的名字命名(比如Navigator,history等)。
-
避免滥用变量。
// Wrong const afetrship = 'Automizely'; // 没有用的就删掉吧。 function func() { let a = 1; let b = 2; let c = 2 * a + b; return c; } // Correct function func() { let a = 1; let b = 2; return 2 * a + b; }
-
对于求值变量,做好兜底,好用的可选链。
// ?.
函数
-
对于返回true or false的函数,最好以should/is/has开头。
function isEmpty() { return false; }
-
动作函数要以动词开头。
function sendEmailToUser(user) { .... }
-
功能函数最好为纯函数
// Wrong function Add(a, b, c){ var c = fetch('../api'); // 这个函数的输出将变化无常。 return a+b+c; }
-
if
判断避免不必要的多层嵌套。尽早Return// Wrong if (condition_a) { do_thing_a(); } else if (condition_b) { do_thing_b(); } // Correct if (condition_a) { do_thing_a(); return; } if (condition_b) { do_thing_b(); }
-
如果有需要,请在函数的开头就进行判断。尽早Return
// Correct function func(argument) { if (!argument) { return; } do_things(); }
-
不要忽略If语句中的花括号。
// Wrong if (condition_a) do_thing_a(); // Correct if (condition_a) { do_thing_a(); }
-
多重判断时使用
Array.includes
。function test(fruit) { // Unsuitable if (fruit == 'kiwi' || fruit == 'pear' || ...) { console.log(fruit); } // Correct const fruits = ['apple', 'strawberry', 'cherry', 'cranberries']; if (fruits.includes(fruit)) { console.log(fruit); } }
-
不要if地狱,倾向于Switch语句,最好是对象遍历。
// 不合适的 if(condition){ }else if(condition){ }else if(condition){ }...
尽量使用ES6以后的新语法
- 模版字符串
${}
代替传统+
。 - 解构赋值代替传统赋值。
TS Coding
-
枚举enum、type、interface命名首字母大写。
// Unsuitable export enum TaskStatus { processing = 'processing', finished = 'finished', } // Correct export enum TaskStatus { Processing = 'Processing', Finished = 'Finished', }
-
不要
any
React Coding
- 你可能不需要使用派生 state。
- 组建跨层级通信时,请注意props传递深度。太深的场景往往需要状态管理或者Context。
- 根据diff算法的设计原则,请尽量减少组件层级深度。同时注意唯一key的设置。
- 请注意undefined带来的渲染异常,做好预防和兜底。
- 不要在循环、条件或嵌套函数中调用 Hook。
- 由于函数组件每次渲染时都会重新执行,所以常量应该放置到函数外部去,避免每次都重新创建。而如果定义的常量是一个函数,且需要使用组件内部的变量做计算,那么一定要使用 useCallback 缓存函数。
- 注意框架提示的每一个warning。
总结
请认证对待你的每一行代码编写,每次提PR之前自己先review一下。
不能总想着重构解决,拒绝先这样吧,没有以后再说。