接手前端新项目?这里有些注意点你可能须要留意一下

前段时间加入公司内一个新开业务线的前端组,因为是新开的业务线,作的也是小程序这一块,因此几乎没有任何历史包袱,组内成员都是项目代码第一手产出者css

我加入的时机较晚,没有经历过最开始的初创阶段,不太清楚一开始的情况,不过据说是蛮折磨人的,须要踩坑无数,常常须要加班(虽然互联网行业加班原本就是常态,不过如今熬过初始阶段就好多了),这让我即庆幸又遗憾,庆幸的是我不用加班那么晚了,遗憾的是,没有参与到一条崭新开业务线最开始的创建阶段,不知道之后还有没有这个机会了html

不过,我加入的时机也不是太晚,项目依旧存在不少须要填补的地方,通过这段时间对代码的阅读,以及平时在作需求过程当中所遇到的问题,从前端方面,暂时总结出了一些关于项目架构或构建可维护代码方面的小小经验。前端

组件化开发最佳实践

如今前端的组件化开发基本上已经成为主流了,既然已是组件化开发了,那么天然就要遵照一些组件化开发的最佳实践vue

每一个组件文件代码总行数不要超过 400

至于为何是 400行,这个数字是我当初在某篇技术文章上看到的,至因而哪一个我忘记,可是不知为什么印象很深入,一直记着,而且根据我多年具有的经验来看,这个数字仍是蛮准确的,通常要么不会超过这个数,或者在这个数字左右徘徊,要么就是比这个数字大不少的webpack

这些都很好理解,既然是组件化开发,那么若是一个组件文件体积太大,存在几十个方法、几十个 data数据(若是用的是 vue框架),那就说明这个组件大几率包含的功能点太多,是能够被继续细化出多个单一功能的子组件的git

太多的方法与 data数据,对于开发者来讲根本就是一种折磨,别的不说,单是给这些方法起名字以及查找都是一件麻烦事,至于往后的维护,那更是噩梦通常的存在,哪怕是当初亲手写下这些代码的程序猿,过一段时间再让他来维护这些代码,他十有八九都要如履薄冰,尽管确认了好多遍,但仍是会担忧本身修改某个数据或者某个方法,会不会对之前某个较为隐蔽的逻辑形成什么不可预知的破坏,因而一遍又一遍地在几十个方法与数据间测试、检查程序员

我曾经看到过包含七十多个 data的组件github

这种状况还算是好的,碰到不负责任的程序猿,可能直接就嫌麻烦,随便在一大堆代码中找个地方写下本身的新代码,检查都不检查就立马提测上线了,由于反正之前上了那么多需求,不当心搞乱了其中某个需求的逻辑,谁特么知道?web

这还仅仅是往旧代码中加新代码罢了,若是是下线以前过时的活动代码,或者删除无用的逻辑,那就更让人掉头发了,几十个方法、几十个数据缠在一块儿,谁知道哪些方法与方法、方法与数据、数据与数据间有着怎样的联系?删掉了这段看起来应该是无用的代码,会不会致使其余有用代码出什么故障?算了算了,不删了,反正后端接口已经关掉,这段代码也显示不出来,就暂时放在上面吧。 却不知,这所谓的暂时,就是海枯石烂的永远小程序

爷爷爷爷,这段代码真的是你写的吗?

因而,页面上无用代码愈来愈多,旧代码与新代码交相辉映,文件体积迅速增大,随着时间的推移,原本轻装上阵的新鲜代码库,逐渐背上了一个又一个历史包袱,而后被后面接手的人大骂,这写的究竟是个什么东西?

世上本没有历史包袱,丢包袱的人多了,也就有了历史包袱。

每一个函数不要超过 100行

这是接上面的,想一想也能明白,一个组件最好不超过 400行,只是一个方法就超过了 100行,那还怎么写? 固然,这里的数字 100根据个人经验,也是蛮准确的,超过这个行数,好好想下,这个方法是否是包含了太多逻辑,遵循函数功能单一原则,不要让一个方法函数包含过多的逻辑功能,是用于拉取数据,那就让它只拉取数据,是用来整合字段的那就让它只整合字段,别干其余的事情

多么性感的臀部啊,答应我,别用它来拉shi好吗?

这样一来,方法函数不只功能明确,维护起来没必要畏手畏脚,同时也可以增长方法的复用性,例如,A方法中包含了拉取页面基本数据的功能,后来需求迭代,另一个后来添加的 B方法也须要拉取页面基础的功能,刚想复用以前 A方法,发现 A方法中除了拉取数据的代码,还有判断是否显示弹窗、修改数据字段、埋点等多个用 if...else...连起来的代码,因而写 B方法的人为了不麻烦,或者发现根本没法复用,只好又把拉取数据的功能重写了一遍

固然,这只是一个原则,实际需求中,若是某两个功能逻辑就是紧密联系不可分割的,你也能够写在一个方法中,总之,在参考这个原则的前提下,灵活变通

定义方法与数据要物以类聚

指具有类似能力或者共同做用于某个功能的方法和数据,最好定义在靠近的位置,方便查找,某个功能受到那些方法和数据所控制,某个数据体包含哪些字段全都一目了然,不管是之后要修改仍是删除,都能作到成竹在胸,不会遗漏

像我这么 diao的还有 107个

例如,页面上与业务无关的工具方法,要放到一块儿,最好所有放到最后,用户信息的数据都定义在靠近的位置,若是你用的是 vue,那么与模板渲染无关的变量,不要放到 data中,既提高了渲染性能,也易于区分变量的功能

// 工具方法都放到一块儿
// 金额 分 转 元
fen2yuan(fenNum) {
  return fenNum / 100
}
// 修改连接协议
changeUrl(url) {
  return url.replace('http', 'https')
}

// 用户信息的数据都定义在靠近的位置
// 固然,你甚至能够把下面这些数据,都定义在一个大的对象中
let avatar = 'https://avarat.com/a.png'
let userName = '小明'
let age = 19
复制代码

顺带一提,CSS的书写最好也按照这种规则,CSS书写顺序的判断依据是 css代码影响的方面,例如,影响元素位置的属性 left top,影响元素长相的 color background,字体 font-size font-weight,这些有同类功能的最好都写在一块儿

另外,我习惯于把能引发页面回流的放在能引发页面的重绘属性的前面,对元素 影响程度 越高的属性越放在最前面,至于什么叫 影响程度 我也说不清楚,下面是我通常写 css的属性的顺序,你们能够自行领悟一下

<!-- position 放在最前面 -->
position: relative;
<!-- 而后是参照 position 进行定位的属性 -->
top: 100px;
left: 10px;
<!-- 而后是宽高 -->
width: 100px;
height: 100px;
line-height: 20px;
<!-- 而后是 margin padding -->
margin: 10px;
padding: 20px 30px;
<!-- font -->
font-size: 20px;
font-weight: 700;
<!-- border -->
border: 1px solid red;
border-radius: 4px;
<!-- background -->
background-color: pink;
<!-- z-index -->
z-index: 10;
复制代码

一开始我也不习惯这种略带有束缚的写法,可是时间长了就习惯了,这些属性的书写顺序,彻底不用思考就迅速依次写下,甚至有时候看到别人写的乱七八糟不符合本身习惯的写法,还会顺手改一改。

这样作的好处是易于查找和维护,想改 width,那就确定是在这个元素 css属性序列的最前面,想改 background,那确定就从后面扫,也避免了在元素属性过多的状况下,可能致使的某个属性出现屡次的状况,我曾经不止一次在代码库中看到某个属性,例如 background写了两次的事情,一个 background写在属性序列的上半部分,而后可能因为这个元素的属性太多,后来维护的人没有看到那个 backgound,或者太乱了也不想看,因而就直接在属性序列的最后面又写了一个

抛开上述的好处不说,最起码这种有条理、有顺序的书写次序,对于某些星座的人来讲,看着也赏心悦目,无形之中也能让本身与外面那些妖艳贱货区别开来

努力学习却不装逼,那将毫无心义

必要而准确的注释

须要长期维护的项目,必要而准确的注释必不可少,甚至宁滥勿缺

一行代码写下去,或许你三天以内还能知道本身当初为何这么写,里面的变量表明什么意思,有什么做用,可是一个月后呢,半年后呢,一年后呢?就算你记得,其余人呢?

我不知道这段代码的做用是什么,可是把它删掉程序就不正常了

若是让你维护一段你早就不记得是谁写的,也不知道到底表明什么意思代码,你要作的第一件事确定就是先看代码,弄明白到底什么意思,而后才能进行后续维护,而对于某些较为复杂的逻辑代码,例如网站首页,里面嵌入了数十个弹窗,这数十个弹窗分别对应数十个功能点,让你修改其中某个 A弹窗的弹出逻辑,而且还要与另外某个 B弹窗进行优先级配合,光是弄明白A、B弹窗的逻辑你都要花费很多时间吧?

而若是在这段代码上面就有一行对这行代码的准确注释,就算你稍后仍是须要读一遍代码,也确定比没有代码时,你理解的更快更准确

一段代码节约一点时间,那么十段呢?一个文件的代码呢?整个代码库的代码量呢?

因此千万不要以为注释无关紧要,仍是那句话,宁滥勿缺,宁愿多写点也不要少写点,你写的代码都是给人读的,反正如今基本上都接自动化打包编译工具(例如 webpack),注释这些东西最后在项目发布阶段都会自动删掉,也不会占用代码体积

变量和方法的命名最好有必定的规律

一样是为了更好的阅读体验,也是为了不过渡注释(宁滥勿缺固然可行,可是少写点无用的注释总不会是坏事),最好的注释就是让代码本身“说出”本身的做用,即命名要有规律性

例如,用于存储数组的变量以 List做为名字后缀,用于某种信息的对象变量以 Info做为名字后缀,用于判断某种逻辑的变量以 is最为前缀,这样一眼看上去就知道变量的大体功能,避免出现让 object类型的对象调用 map的蠢事

const namesList = ['xiaoming', 'xiaohong']
const userInfo = {
  name: 'John',
  age: 20,
  gender: 'male'
}
const isEven = 10 % 2 === 0
复制代码

方法的命名同上,另外,为了更容易体现出方法的功能点,方法的名称最好不要太“宽泛”,例如拉取数据的方法,最好不要命名为相似 getData这种,由于若是这个组件中还存在其余的拉取数据方法,就容易让人迷惑,不会那么一会儿就知道这个 getData究竟是针对哪一个数据接口的,应该进一步精确到相应的接口,例如命名为 getUserData

关于如何给变量以及方法命名这件事,存在不少细致的解决方案,能写两篇文章出来,就不一一展开了

通用的功能要封装成组件

通用的组件,最好肯定好功能点后,封装成统一的通用组件,通用组件必定要覆盖大部分的通用功能点,不然还不如不要

大一点的,例如弹窗,可能包括标题、关闭按钮、内容、遮罩层这些结构,小一点的,例如页面的遮罩层,主体包括一层遮罩样式,那在封装这个组件的时候,就要把这些结构考虑进去

我曾经看到过某个组件中,包含了多个弹窗,可是没有封装通用的弹窗组件,因而相同的元素以及样式被写了好几遍,印象最深入的是遮罩层元素也出现了好几遍,每一个弹窗都专门写一个遮罩层样式,写过的人都知道,单是这一个遮罩层的样式都有好几行了,何苦来哉

DRY原则

Don't repeat yourself

这一条能够与上条结合使用,不管你是写什么代码,需求是长期仍是短时间的,做为一个有素质的程序猿,你最好都要遵照这条规则

这里的 DRY,不只是指彻底如出一辙的代码字母,还在于一样的逻辑,这里举个例子,表单验证是很常见的场景,通常的验证方法都是不假思索的数个乃至是数十个 if语句依次排列,整整齐齐气势惊人,但问题是几个 if语句连在一块儿或许不太明显,难以触碰到你的 G点,可是十几个乃至是几十个 if语句堆在一块儿,你难道还能不以为别扭吗?

if (age > 19) {
  // ...
}
if (name.indexOf('zhao')) {
  // ...
}
if (gender === 1) {
  // ...
}
if (weight > 75) {
  // ...
}
// 无穷无尽
// ...
复制代码

只要我复制粘贴得足够快,bug就追不上我

关于表单验证这个东西,有篇文章写得很好,你们能够参考一下

单独的业务代码之间、业务代码与非业务代码之间进行必要的隔离

业务代码,以 if...else琳琅满目为主要标志之一,多个需求的业务代码混合在一块儿那就意味着数倍琳琅满目的 if...else,若是再在这些 if...else中躲猫猫般穿插进非业务代码,那么恭喜你,现在你获得的这份代码,其实有个流传于江湖已久的响当当名号:意大利面条式代码

隔离单独的业务代码,可以直接减小头发掉落数,能间接下降 bug出现率,这很好理解

通常的项目都是长期迭代而来,一个页面上可能堆积了数十个需求的功能点,每一个功能点都对应几大段的方法和数据,而且这些需求还可能从诞生到如今被修改了数次,搞很差有的业务间还存在相互依赖与重叠

若是把这些业务包含的方法和数据全都放在一块儿,那酸爽……诶,这个方法是属于A需求的吗?若是是那为何这里面还包含了B需求的数据?怎么这里还调用了C需求的方法?C需求的这个方法修改的这个数据是C需求的吗?看起来不太像啊?算了算了,应该是,先这样写吧,等测试提 bug了再说……

下班晚不是由于你需求多,而是你本身写得代码给你找的事多

与位置无关的元素汇集书写

若是页面上元素少的话,或许没有区别,可是当页面上存在大量元素,例如网站首页、商品详情页这些比较重要的页面,就很容易感受出来了

modal弹窗、toast等辅助性元素,页面上可能存在好多个,这种元素通常与位置无关,样式设置的都是 position: asbolute或者 position: fixed;,不管放在哪一个位置基本上都 ok,那么建议找好一个固定的位置汇集存放这些元素,例如页面的顶部或者底部,并写好注释,方便寻找与修改,也方便统计,任意穿插在各类 DOM间,维护起来都是一件麻烦事

<!-- 新手好礼的引导弹窗 -->
<ModalA />
<!-- 领奖弹窗 -->
<ModalB />
<!-- 新人提示 -->
<ToastA />
<!-- 资质不够提示 -->
<ToastB />
<!-- 风险用户提示 -->
<ToastC />
复制代码

删掉没必要要的代码

包括无效代码、注释的代码、没必要要的调试代码

作过活动页的应该都知道,这种活动运营页寿命通常都很短,可是所要付出的精力却很多,活动下线后代码可能就直接无效了,大部分状况下这些失效的活动代码不会对页面有效逻辑产生什么影响,因此赶着进入下一个需求的程序猿们,本着多一事不如少一事的原则,极可能就职由无效代码一直存在于页面,直到地老天荒,这种事情最起码从个人经从来看,很常见

有的需求在开发阶段频繁变更,辛辛苦苦写的逻辑还没来得及被上传到线上服务器就夭折了,恼羞成怒的程序猿不甘心掉落的头发连一点成果都没有留下,因而机智地按下了 Ctrl + /快捷键,幻想着这段被封印的代码总有重见天日的那天,却不知,又是直到地老天荒,这种事情最起码从个人经从来看,很常见

虽然某些自动化打包编译工具支持删除相似于 console.logdebugger之类的调试代码,但问题是在 dev阶段这些代码都是存在的,每一个人在每一个需求中都加入 5个 console.log,那么只须要十我的次,控制台上就能够出现 50console.log,特别是这些 console.log 基本上都是秉持着哪里有位置就写在哪里的原则,就算是想删也须要耗费大量时间,苦逼的程序猿什么都没干,先在控制台看到几十行别人写的 console.log,而后在一堆 console.log中找到本身须要的那个,并在需求完成时,顺便又在原先几十个 console.log的基础上,又贡献了本身的一份力量,这种事情最起码从个人经从来看,很常见

编辑器每多显示一行无效代码、控制台每多输出一行 console.log,都将耗费必定的电量,全球几千万的程序员,聚沙成塔,足以加剧全球温室效应,加速两级冰川融化,可怜的北极熊宝宝和企鹅宝宝找不到爸爸妈妈,人间有真情人间有真爱,请坚决地按下 backspacedelete

良好的沟通,避免无效的产出

永远不要相信 PM说的这个需求确定不会再变了的话

PM改变需求咱们没法劝阻,可是咱们能够明确现有的需求,不写无效的代码,从而进一步避免了大段注释,保住了更多的头发,不要等到快上线的时候,才发现本身好像弄错了某段逻辑,或者少写了某段逻辑,最可恨的是白写了某段逻辑

代码容错

这个世界上不存在没有 Bug的代码,只要你写的不是 demo,那么必定要作好代码容错处理,由于你永远不知道接口给你返回的是 | 仍是 (亲身经历,此梗参见有哪些让你目瞪口呆的 bug?)

还有一些可能不叫错误,例如页面数据的初始化,在获取到数据以前,页面上可能会渲染出 undefined这种鬼东西,为了更好的用户体验,最好仍是给个体验更好的初始值吧

遵照制定好的规范

多人协做规范很重要,不管是 jshint 仍是eslint大行其道就是明证

,对于一个项目来讲,规范可能包括从 es版本、缩进类型到页面结构、组件拆分等,你既能够直接照抄成熟的规范,也能够自定义规范,但不管是什么样的规范,只要制定下来,那就要遵照,不要因我的缘由,与团队貌合神离

有种效应叫破窗效应,这个项目中出现了不同的风格,后来进入的人第一印象就是规范也不是那么严谨,偶尔打破一下也是能够的,而后又有后来的人看到,第一印象就是……因而不一样的风格越积越多,规范也就无从谈起了,从一开始就稳不住,难道还想着半路忽然硬一下?

你能够不喜欢项目如今的页面结构划分方式,也能够认为路由的划分方式很SB,但既然你在当初制定这个规范时没有反对没有提出异议(不管是忘记了仍是被无视仍是没有机会提,总之当初你没反对),那么如今就要遵照,或者你也能够尝试着改变这个规范,但请作好善后事宜,例如确保在新规范制定后,项目中以前存在的老规范要被所有修改过来,坚定保证代码风格统一化,至因而谁来作这种吃力不讨好的事情,你懂得。

本身挑的shi,跪着也要吃完

按期的代码 review

旁观者清,本身通常很难发现本身的错误,不然的话也不会那么容易触犯了,不管是代码的规范仍是逻辑的误差,有些错误若是其余人不及时指出来,咱们可能永远没法意识到,按期的代码 review就可以很好地解决这个问题

不过,代码虽好,也不必 review得太频繁了,否则只会变成一种负担,你们都这么忙,谁没事帮你每天 review代码

必要的踩坑与经验文档

这个 很重要,不管你用的是什么框架,写的是小程序仍是 webview,确定都存在着各类各样的坑,若是老旧代码有历史包袱不想搞的话,那么新启项目就要好好对待了,文档改写的就要写,不要怕麻烦,不过等到新人加入,或者干脆是移交他人的时候,你就知道什么叫 敲码一时爽,交接火葬场了

小结

曾经看到过某个帖子,大意是 题主认为大部分前端作的事情,其实不管是五年经验仍是外包或者实习生都能作,凭什么五年经验人拿得工资就高?

我当时也是闲得蛋疼,回答:这个问题不只仅是在前端,后端、客户端等各类领域都会给你这种错觉,我之前也是这么认为的,后来某天当我看到一个相同的 bug,组长看了一眼就准肯定位并顺手解决,而实习生抓耳挠腮了大半天,不只没能明白究竟是怎么回事,甚至还多引入了几个 bug后,我就知道人家那么多钱不是白拿的

固然,大部分工做经验高拿钱多的人并非仅仅是靠改 bug快这一个缘由,另外也不排除有些人原本就天赋异禀,只工做了一年但能力抵得上别人工做三年的,而有些人工做三年只有一年的能力