最近在工做中遇到了比较紧急的项目,短期以及不能再删减(甚至还可能会变)的需求就意味着要尽量地提高开发效率。前端由于与交互相关,所以会受到大部分需求变动的影响。如何尽量地减小因需求变动而产生的工做量,一直以来都困扰着前端开发人员。javascript
因为本身平时的代码风格还不够规范以及知识领悟不深,天然我也没少受苦,但也所以对提升开发效率方面有了一些体会。本文即是总结与复盘,用于往后提醒本身。前端
对于咱们作开发的同窗来讲,提升工做效率最有效的方法就是下降 BUG 率;而下降 BUG 率最有效的方法就是减小代码量。还记得 GitHub 上以前大火的项目 No Code 吗?资深的谷歌工程师告诉咱们,一行代码都没有的程序是最安全的稳定的。java
其次若是代码拓展性足够强,那么在面对需求变动时的工做量就会相对减小(做为前端,不变动时不存在的)。而加强代码拓展性比较经常使用的方法就是通用组件的封装与抽象。git
下面就是有关于这两部分的一些总结和思考。程序员
良好的代码风格应该是下降 BUG 最有效的方法,能够参考《代码整洁之道》一书。下面的一些方法是我在平时工做中所总结出来的几点。github
代码量越少也就越难出现 BUG。在平时的工做中,应该尽量地减小编写的代码量。在前端中,最简单的就是尽可能使用 ES6 语法。相比 ES5,经过 ES6 的解构、箭头函数、async/await 能够减小 30% 以上的代码量。在有大量(3 个以上)的 if
判断时,可使用对象的形式。编程
// 常规赋值操做
let a = 1
let b = 2
let c = 3
// 使用解构赋值
let [a,b,c] = [1,2,3]
// 使用 if
if(a === '1'){
....
}else if(a === '2'){
...
}else if(a === '3'){
....
}
...
// 使用对象进行分类处理, 逻辑上会更简洁一点
// PS:这个方法在 React 进行组件渲染的时候很是有用
const handleAction = (act) => {
const actions = {
'1': action1,
'2': action2,
'3': action3
}
const action = actions[act]
action()
}
// 根据状况进行处理
handleAction('1')
复制代码
在 React 的项目中,若是使用了 Redux。那么应该尽量地使用 function
组件来减小代码。同时这么作也可让咱们在进行 UI 移植的时候省下不少改动(最近有一个项目是部分功能的迁移,Redux -> dva
在移植 function
组件时几乎没有什么改动),并且如今有了 Hook,function
组件中不能控制 state
的问题也能解决。json
缺乏默认值很是容易形成 BUG,这是以前一个项目中血和泪的教训。特别是 React 项目中使用了上面介绍的对象的方法进行组件切换时,若是没有设置默认值就会直接形成页面崩溃。api
class A extends React.Component {
const Components = {
// 特别是根据 Response 来进行组件切换时,应该设置 default 防止意外状况
A: Component1,
B: Component2,
C: Component3,
'default': () => <div />
}
render(){
const {render} = this.state
// 若是没有默认值,一旦对象匹配不到,页面直接崩溃
const RenderComponent = Components[render] || Components.default
return (
<RenderComponent /> ) } } 复制代码
其次函数参数的默认值除了能减小 BUG 外也能帮助减小代码量。对于使用次数较多的方法,直接设置默认值可让咱们在调用时省去参数的传入。安全
// 当 0.0.0.1 和 api service 方法较多时,设为默认参数能够减小参数的传入
function customizeFetch(service='api', base = '0.0.0.1'){
...
}
customizeFetch()
复制代码
说到拆分函数,用的最多的应该是 request
的应用部分。好比对 fetch
的封装。
// 封装好的 fetch (有柯里化的影子在)
function customizeFetch(server = "api", base = "0.0.0.1") {
return function(api = "", options = {}, withAuth = false) {
const url = `${base}/${server}/${api}`;
const opts = {
method: options.method || "POST",
headers: {
// 能够设置默认参数,好比头什么的
...options.headers
},
body: {
...options.body
}
};
return fetch(url, opts).then(response => response.json());
};
}
// 当咱们进行调用时,对于业务来讲写起来基本一致
// 因为使用透传,其实在 service 还能偷懒写成一个方法
// 产品列表
const fetchAPI = customizeFetch("api1");
const getProductList = opts => {
const options = {
body: { ...opts }
};
return fetchAPI("getProductList", options);
};
// 新闻列表
const fetchAPI = customizeFetch("api2);
const getNewsList = opts => {
const options = {
body: { ...opts }
};
return fetchAPI("getNewsList", options);
};
复制代码
eslint
的好处就不用提了吧?再配合 prettier
可让代码格式统一(umi
的 lint
虽然在不习惯时会以为很烦,可是一旦习惯后对代码风格的提高仍是颇有帮助的)。若是再用上 TypeScript
更是可让咱们在编码时检查到错误。TypeScript
虽然在刚开始使用时很不习惯,特别是对于类型的强要求(所有 any
的话等于没有类型)很头痛。不过适应以后就能体会到 TypeScript
带来的快感了。
在引入 TypeScirpt
以后,最容易出现的 xxx from undefined
错误就能彻底避免。能够帮助咱们节省下许多调试的时间。
前端的组件化开发,在更多的程度上是为了应对需求的变动(我的认为)。而因为前端是最接近用户的,所以只要需求有变是逃不过要进行一番修改的。所以让修改的工做量减小以及减小因修改带来的 BUG,也是提升效率的方法。
对于 React/Vue 项目,只要使用了 Redux/Vuex 这类状态管理工具,咱们就能很容易地把组件作成不依赖于 state
的 stateless
组件。这类组件很“纯”基本只依赖于传入的 props
,即使有 state
也是属于自治范围,不会参与业务逻辑计算。这么一来就能尽量地让 UI 层更加纯净,职责更单一。(固然这只是一种美好的愿望,实际上根据反作用切换组件状态或者其余业务逻辑操做仍是会让业务逻辑下沉到 UI 层去)
让 UI 层尽量地变得简单,而处理业务逻辑的部分就应该转移到 Redux 的 action
的部分中。Reducer
的部分也应该尽可能纯净,不作业务处理。这样若是当需求有变化的时候,修改的部分就能尽量地被缩小在 action
部分,同时在作项目移植时也会比较方便(基本 action
层很大可能会重写)。固然实际中并不可能剥离得很是干净,UI 层每每也会跟着一块儿变更,不过仍是能够减小修改的范围。
另外一个就是根据项目需求提炼出通用的业务组件,好比短信验证码、可编辑 label
的表单控件、权限验证组件、搜索组件等。这类组件基本与业务相关,基本是某个组件库的再封装(好比 antd
),这个也是如今许多同窗平时会作的。这样在某一个业务中能够减小咱们的开发量。具体的可使用 HOC 等方法来进行封装和抽象(好比权限验证组件)。
提炼组件当然不错,可是也要避免过分封装。曾经在写 Vue 的时候封装了一个可配置的表单组件,结果当业务须要两个表单控件的互相控制以及按钮状态控制时就傻眼了。所以在设计封装组件时也要考虑到以后业务的变化。
以上即是最近这段时间的一些工做感悟,算是做为本身的一个备忘。编程本来的目的就是提升作事的效率,而提升开发的效率又是每个程序员都要面临的难题。因此编程是一件十分有意思的事情,其中一点就是能够不断地挑战和提高本身。