前端JavaScript开发风格规范
开发者需要建立和遵守的规范
大致可以划分成这几个方向:
- 开发流程规范
- 代码规范
- git commit规范
- 项目文件结构规范
- UI设计规范
1. 开发流程规范
这里可能有小伙伴有疑问了,开发流程规范不是项目经理定的吗,跟我有什么关系?
这里想告诉大家的是,开发流程在一定程度上应该是由我们自己来掌控。不管是传统开发的模式还是敏捷开发的模式,对于开发者来说核心依旧是高质高效的完成用户提出的需求
。
笔者曾见过不少开发者在拿到产品经理的需求后就开始急匆匆的写代码,以此来体现他们的高效
,但往往却因为需求理解不到位和前期代码欠缺设计导致bug率高和返工。
如何找到适合自己的开发流程是需要依靠经验来支撑的,需要反复总结和思考,最终达到高质高效完成
的目的。
说一说笔者自己比较喜欢的开发流程:
在接收到需求后应第一时间去了解这个需求的背景是什么?
这么做到底有没有解决用户的痛点?或者说用户更深层次的需求是什么?如果团队的产品经理经验不丰富,往往可以在这个阶段砍掉很多不合理的需求(这一点真的很重要)
。
对于复杂大功能往往还需要进行技术方案调研
和技术方案设计
,并输出详细的设计文档。涉及到细节上,则需要将数据流走向、组件设计等通过脑图的形式呈现出来。
2. 格式化规范
由于每个开发者的IDE不同,即使IDE相同也会因为每个人的配置不一样导致格式化的结果不一样。如何确保团队内开发人员采用统一的格式化配置呢?
这里给推荐大家使用 prettier,它内置了一套格式化的规则,具体配置:
配置编辑器(VScode为例)
IDE中安装 Prettier-Code Formater插件:
找到IDE中设置模块,搜索 format On Save,勾上这个就可以了。
现在当我们 Ctrl + S 保存代码时,插件就会帮助我们自动格式化了。
其他:若使用的是脚手架工具搭建的项目,会自带eslint配置(eslintConfig
)。prettier 和 eslint 会有一些配置上的冲突
,这个时候需要安装eslint-config-prettier 以使 ESLint 和 Prettier 相互配合,安装完后在.eslintrc
中配置(以Create-React-App为例):
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest",
"prettier"
]
},
这样就可以用"prettier"
的部分规则覆盖前面的规则,让它们都能正常工作。
3. JS/TS规范
JS/TS主流的大致有这几种:
- Airbnb JavaScript Style Guide
- Google JavaScript Style Guide
- Idiomatic JavaScript Style Guide
- JavaScript Standard Style Guide
- jQuery JavaScript Style Guide
比较推荐使用 Airbnb JavaScript Style Guide,它在 Github 上足有 12万 star,几乎覆盖了 JavaScript 的每一项特性。
由于Github国内访问限制,这里贴上码云的访问地址:
Airbnb JavaScript Style Guide 中文翻译 For ES6删减版
4. CSS规范
CSS检查代码规范使用 stylelint
插件,规范则推荐使用 stylelint-config-standard
5. 自定义其他规范
下面列一些团队内定的其他规范:
(1)命名规范
变量的命名中应尽量减少缩写的情况发生,做到见名知意。
// 自我感觉良好的缩写:
let rContent = 'willen'; // 无需对每个变量都写注释,从名字上就看懂
let firstName = 'jackie'; // 从命名无法知道返回值类型
function showFriendsList() {....} // // 无法辨别函数意图,返回的是一个数组,还是一个对象,还是true or false? // 明确函数意图,对于返回true or false的函数,最好以should/is/can/has开头
function shouldShowFriendsList() {...}
function isEmpty() {...}
function canCreateDocuments() {...}
function hasLicense() {...}
function sendEmailToUser(user) {.... } //动词开头,函数意图就很明显
(2)写注释
在每个文件的顶部明确说明该组件做什么,有没有业务理解难点等等,对业务特殊函数/变量也需要写注释
/**
* 导航页面-右边区域
*/ const Content=>()=>xxx const MAX_INPUT_LENGTH = 8; //用于限制密码输入框 function Component(props) {
return (
<>
{/* 如果用户没有订阅则不展示广告 */}
{user.subscribed ? null : <SubscriptionPlans />}
</>
)
}
(3)变量兜底
// 对于求值获取的变量,没有兜底
const { data } = getApiRequest();
data.map((s) => s.id); //没有考虑data异常的情况,代码一跑就爆炸 // 对于求值变量,做好兜底
const { data = [] } = getApiRequest();
data.map((s) => s?.id); //没有考虑data异常的情况,代码一跑就爆炸
(4)辅助函数必须是纯函数
// 不要让功能函数的输出变化无常
function plusAbc(a, b, c) { // 这个函数的输出将变化无常,因为api返回的值一旦改变,同样输入函数的a,b,c的值,但函数返回的结果却不一定相同。
var c = fetch('../api');
return a+b+c;
} // 功能函数使用纯函数,输入一致,输出结果永远唯一
function plusAbc(a, b, c) { // 同样输入函数的a,b,c的值,但函数返回的结果永远相同。
return a+b+c;
}
(5)优先使用函数式编程
// 使用for循环编程
for(i = 1; i <= 10; i++) {
a[i] = a[i] +1;
} // 使用函数式编程
let b = a.map(item => ++item)
(6)优先使用函数式组件
除非需要用到错误边界,否则函数式组件应该是首选方法。
(7)组件复杂度
如果一个组件做的事情太多,应适当提取一些逻辑,将其拆分为更小的组件。
如果提取的组件很复杂,则需要依照一定的规则和条件一一提取它。
代码行数并不是一个客观的衡量标准,更多是需要考虑责任划分和抽象。
(8)用错误边界
当需要对大量数据进行渲染处理时,需要通过错误边界组件对其进行降级处理。
更多详情见专题文章:浅析前端异常及降级处理。
function Component() {
return (
<Layout>
<ErrorBoundary>
<CardWidget />
</ErrorBoundary> <ErrorBoundary>
<FiltersWidget />
</ErrorBoundary> <div>
<ErrorBoundary>
<ProductList />
</ErrorBoundary>
</div>
</Layout>
)
}
(9)props参数传递
props一层层传递一直是我们很头疼的一个问题,最核心的问题是不清楚props是从哪个初始组件传来的,以及props中到底有哪些东西,上下文是什么?
因此对于传递较深的场景我推荐直接使用 context,对于 props 中的内容和上下文通过 TS 来解决。
// A.tsx
interface AProps {
param: string;
}
const A = ({ param }: AProps) => {
return <B param = {param} />;
}; // 上下文清晰
// B.tsx
const B = ({ param }: { param: AProps['param'] }) => {
return <div>hello world</div>;
};
(10)props传参数量
如果超过 5 个props,就该考虑是否拆分该组件。在某些情况下,这是需要对组件进行重构的标志。
注意:组件使用的props越多,重新渲染的理由就越多。
(11)避免嵌套三元运算符
三元运算符在第一级之后变得难以阅读,虽然看起来节省了代码空间,但最好在代码中明确意图,保持良好的阅读性。
// 不够清晰,要是再嵌套一层两层呢
isSubscribed ? (
<ArticleRecommendations />
) : isRegistered ? (
<SubscribeCallToAction />
) : (
<RegisterCallToAction />
) // 将判断逻辑进行拆分
function CallToActionWidget({ subscribed, registered }) {
if (subscribed) {
return <ArticleRecommendations />
} if (registered) {
return <SubscribeCallToAction />
} return <RegisterCallToAction />
} function Component() {
return (
<CallToActionWidget
subscribed={subscribed}
registered={registered}
/>
)
}
(12)将列表组件封装成独立组件
// 列表渲染和其他逻辑杂糅在一起
function Component({ topic, page, articles, onNextPage }) {
return (
<div>
<h1>{topic}</h1>
{articles.map(article => (
<div>
<h3>{article.title}</h3>
<p>{article.teaser}</p>
<img src={article.image} />
</div>
))}
<div>You are on page {page}</div>
<button onClick={onNextPage}>Next</button>
</div>
)
} // 将列表组件提取出来,一目了然
function Component({ topic, page, articles, onNextPage }) {
return (
<div>
<h1>{topic}</h1>
<ArticlesList articles={articles} />
<div>You are on page {page}</div>
<button onClick={onNextPage}>Next</button>
</div>
)
}
(13)避免嵌套渲染函数
// 不要将其定义在渲染函数组件中
function Component() {
function renderHeader() {
return <header>...</header>
}
return <div>{renderHeader()}</div>
} // 将其抽离到独立的组件中去
import Header from '@modules/common/components/Header' function Component() {
return (
<div>
<Header />
</div>
)
}
(14)组件/函数导入导出
// 在文件头部导入,顺序依次为: 第三方库 > 公共组件/方法 > 非公共部分组件/方法
import React from 'react'
import _ from 'loadsh'
import Header from '@components/header'
import Content from './Content' // 在底部导出
export { Content, Header }
export default Component
6. 项目文件结构规范
不得不说,在这件事上我们团队曾经花费了大量的经历去思考和实践,也是信了React官方的鬼话:不要花超过五分钟在选择项目文件组织结构上。
在项目初期若不重视,到了后期就是到处天马行空,你很难在期望的目录下找到你想要的文件。
文件夹名称全部采用小写 + "-" 来隔开,index.ts更多是用来做导出作用,要不然最后编辑器中满屏的index.tsx,很难区分。
通过对工具函数、hooks、api 等加上后缀,更加容易区分引入的文件。
7. Git commit规范
git commit 规范主要可以帮助开发人员在 code review 期间更容易理解提交的内容,现在大部分主流 commit 规范都是基于Angular 团队的规范而衍生出来的,它的 message 格式如下:
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
每个提交消息都包含一个subject、一个body和一个footer (中间使用空行分割),提交信息的任何一行不能超过 100 个字符。
type主要有以下几种类型:
- feat: 一个新特性
- fix: 修复bug
- docs: 文档修改
- style: 不影响代码含义的更改(空格、格式、缺少分号等)
- refactor: 代码重构
- perf: 优化性能
- test: 测试用例修改
- chore: 对构建过程或辅助工具和库的更改,例如文档生成
scope:可以是影响范围的任何内容。
subject:包含对更改的简洁描述,规则:
- 使用陈述语句
- 第一个字母不要大写
- 末尾没有点 (.)
body:commit 具体修改内容, 可以分为多行,应该包括改变的动机,并与以前的行为进行对比。
footer: 一些备注, 通常是修复的 bug 的链接。
截取一张开源库的 commit,example:
有了规范后,我们需要通过工具去约束:commitlint。它要做的就是在我们每次提交 git commit
的时候,都会帮我们检查 commit message
是否符合一定的规范,如果不符合,就让这次提交失败。
具体配置:
# 安装 commitlint cli 和 conventional config
npm install --save-dev @commitlint/{config-conventional,cli}
# Windows:
npm install --save-dev @commitlint/config-conventional @commitlint/cli 配置要使用的 commitlint 规则
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js 加入到husky中:
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
or
yarn husky add .husky/commit-msg 'yarn commitlint --edit $1'
8. UI设计规范
优秀的开发者应该反向推动UI的规范,并且能够支撑UI规范的落地。
UI 规范的最大好处就是能够提质提效:
- 在开发者的角度,与设计规范同步形成研发资产,避免重复造轮子;
- 在测试的角度,能够避免重复的无意义走查;
- 在UI设计师的角度,减少设计成本,提高设计效率,可以快速承接新需求;
- 站在产品角度,提高产品迭代与优化效率,降低试错成本;
- 站在用户角度,解决用户体验一致性。
那到底应该怎么去推动UI规范?我的做法是先让设计师去给出一系列的规范,没有相关规范就拉上产品经理一起制定规范。然后前端建立一套自己的组件库,再将组件库提供给UI设计师,以此来相互监督是否达成了规范协议。
具体参考 Antd设计规范。
总结
统一规范的最根本目的是为了保证团队成员的一致性,从而减少沟通成本,提高开发效率。
学会热爱标准,但要确保它们不是一成不变的。如果制定的规范不适合您的团队,请确保可以适应和重写所需要的任何规则。它并不是要强制执行一种工作方式,而是为了帮助促进团队之间的互动 。
前端JavaScript开发风格规范的更多相关文章
- 浅谈前端JavaScript编程风格
前言 多家公司和组织已经公开了它们的风格规范,详细可參阅jscs.info,以下的内容主要參考了Airbnb的JavaScript风格规范.当然还有google的编程建议等编程风格 本章探讨怎样使用E ...
- 前端模块化开发的规范:AMD与CDM
AMD, 异步模块定义. CMD,通用模块规范.
- JavaScript开发规范要求
http://www.cnblogs.com/webflash/archive/2010/06/11/1756255.html 作为一名开发人员(WEB前端JavaScript开发),不规范的开发不仅 ...
- JavaScript 开发规范要求详解
作为一名开发人员(We前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以及执行效率上的问题.本人在开发工作中就曾与不按规范来开发的同 ...
- JavaScript开发规范
作为一名开发人员(WEB前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以 及执行效率上的问题.本人在开发工作中就曾与不按规范来开发 ...
- 翻译:谷歌HTML、CSS和JavaScript风格规范
我喜欢浏览风格规范.他们通常有明显的规则,虽然有些有荒诞之感,但是却可以发现之前未注意到的宝石.不幸的是,鲜有公司有这个勇气来发布自己内部的风格规范.BBC 2010年时候公开其文档以及Google最 ...
- Google JavaScript代码风格指南
Google JavaScript代码风格指南 修正版本 2.28 Aaron Whyte Bob Jervis Dan Pupius Eric Arvidsson Fritz Schneider R ...
- 【转载】webstorm-前端javascript开发神器中文教程和技巧分享
webstorm是一款前端javascript开发编辑的神器,此文介绍webstorm的中文教程和技巧分享. webstorm8.0.3中文汉化版下载:百度网盘下载:http://pan.baidu. ...
- webstorm-前端javascript开发神器中文教程和技巧分享(转)
webstorm是一款前端javascript开发编辑的神器,此文介绍webstorm的中文教程和技巧分享. webstorm8.0.3中文汉化版下载:百度网盘下载:http://pan.baidu. ...
- webstorm-前端javascript开发神器中文教程和技巧分享(转)
webstorm是一款前端javascript开发编辑的神器,此文介绍webstorm的中文教程和技巧分享. webstorm8.0.3中文汉化版下载: 百度网盘下载:http://pan.baidu ...
随机推荐
- Spring框架之控制反转IoC(Inversion of Control)的理解
简单理解: 控制反转就是将代码的调用权(控制权)从调用方转移给被调用方(服务提供方). 解释一下: 如果我们需要创建某个类,就需要程序员去修改代码,然后才可以得到想要的类.反转的意思就是不需要程序员去 ...
- Unity最新一键清理Prefab中所有MissingComponent
因为老的API Properties.DeleteArrayElementAtIndex(propertyIndex);提示没权限修改, 而unity提供了新的API GameObjectUtil ...
- #NTT,原根#洛谷 3321 JZOJ 4051 [SDOI2015]序列统计
题目 分析 首先朴素dp方程 设\(dp[i][j]\)表示\(i\)个数的数列乘积为\(j\)的方案 那么\(dp[i][j*a[k]\bmod m]=itself+dp[i-1][j]\) 这可以 ...
- 【开源三方库】Fuse.js:强大、轻巧、零依赖的模糊搜索库
开源项目 OpenHarmony 是每个人的 OpenHarmony 曹天恒 公司:中国科学院软件研究所 小组:知识体系工作组 1.简介 Fuse.js是一款功能强大且轻量级的JavaScript ...
- OpenHarmony有氧拳击之应用端开发
一.简介 继<OpenHarmony有氧拳击设备端的开发>后,本次为大家带来酷炫的应用端开发.如下,开发者伴随着音乐,律动出拳后,那开发板屡屡播放"挨打"效果,这究竟是 ...
- HarmonyOS账号服务,畅行鸿蒙生态所有应用与服务
账号对于用户来说并不陌生,在购买新设备或者使用新应用的时候,用户常常会被引导注册或者登录账号,账号就是用户在这些设备或应用内的通行证.根据华为上半年的一项统计,整体上中国网民人均下载App量在68个, ...
- AI数字人互动大屏:如何改变我们的生活?
随着科技的飞速进步和人工智能技术的日益成熟,智能制造正在成为推动制造业转型升级的核心力量. 互动数字人具有强大的情感分析能力,可以根据观众的表情.语气等实时反馈,作出恰当而富有情感的回应.这不仅让每一 ...
- Xilinx USB JTAG两种JTGA-HS3和Platfrom下载器速度对比
下面测试速度,以一个V7的配置文件为例子.文件大小如下,27MB.特别是对于有点规模的项目配置文件都是很大的.总不能是点灯项目. 选择普通的下载器,Platform Cable USB.这种下载器是基 ...
- dbeaver导出结果集中乱码
重要的一步 需要点击
- 力扣26(java&python)-删除有序数组中的重复项(简单)
题目: 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度.元素的 相对顺序 应该保持 一致 . 由于在某些语言中不能改变数组的长 ...