献祭体重,拥抱技术,干货和鸡汤我都有|掘金征文

2,177 阅读13分钟

前端是有极限的,bug是无极限的(狗头)

连锁反应

每个人多少会有些感觉,上半年的疫情给很多同学的人生轨迹带来了转折,我们获得了大把单独呆在家时间,表面上很爽:“宅在家也是对社会做贡献”,“终于能名正言顺葛优瘫了”。然而背地里暗流涌动——高校新生全程网课,一人独处,还有手机在侧,专心听讲,略有难度,待到正式开学如何是好;毕业生无法接受导师面对面指导,面临远程答辩,看似很稳实则很慌;次一级的同学,需要面对春招和网课两座大山,翘课面试,过了很爽,不过很煎熬。二月到五月三个多月的时间,合理利用足以“逆天改命”,补齐短板一路高歌;倘若真一路葛优瘫,一身武功就荒废了。

疫情期间,我和“矛盾”相伴,一边懒惰,一边勤奋,有时躺平一动不动,各路视频从早刷到晚;有时却泡在学习资料里连饭都不想吃,只为和面试官谈笑风生,即使饭冷菜凉,依然吃的真香。最终得到如下化学反应:

  • 单身年限 + 1
  • 体重 + 10
  • offer + n
  • 技术深度 + 3
  • 脑熵 + 1

单身贵族/跪族?

首先是单身问题,单身是我的悲哀还是矜持还是命运?真不清楚。解决单身,有时是最难的问题,但有时也是最简单的。不过也不必纠结,狗粮吃多了,底气也足了,反正单身狗贱命一条,横竖都得过,回去窝里一躺,继续追辉夜大小姐。总之,狗龄又长一岁。

增重计划通

作为一名男士,我常常被长辈念叨体重太低,一米八连一百二十斤都没,女孩子在你边上能有安全感?你爸爸年轻时没你高都比你重多了,多有型。疫情宅家一百多天,在坚持每天进行一定量运动的情况下,增长 10 斤体重,突破一百二十斤大关,圆满达成长辈期待。下一阶段目标:保持健康,珍爱颈椎。

offer 界“渣男”

我科班出身,学校后端底蕴深厚,然而却耍叛逆,偏偏选择转向前端,自然遭到报应,曾度过一段艰难岁月。不过还算命硬,熬到春招收获的季节,几乎每次简历出手都有所得,不过毕竟最终只能选择一家,无奈抛弃其他,沦为“渣男”。具体面经和心路历程见我这篇文章:后端转前端的小老弟突然收割大厂 offer,真相竟然是

新技能点 get

技术文章不能只有口嗨,半年来我在项目中运用了 Flutter,并在淘宝的实习中深入 Webpack 和 React 函数式编程,积累了一些经验心得,会按照时间顺序在下文分享。

自我困扰的思考

近年来,前端的袋口比以往收紧了些,“前端天花板低”的论调在社区中层出不穷,作为一名从后端转向前端,兴趣使然的科班,我对此进行了一些思考,会在文章最后分享出来,共勉之。

Flutter 骑驴看唱本

开头所说“翘课面试”,本人是其中之一。课可以翘,但是大作业不能不做,而本学期我的大作业技术选型是 Flutter,当时在学校里和队友吹的天花乱坠,拍着胸脯保证用 Flutter 一套代码多端编译,能很爽的完成一个 App 加一个网站,而且一定要用 beta 版本,尝试最潮的功能,活跃在技术最前沿。结果疫情排山倒海,大家只能线上对接,而 Flutter 的 beta 版本一周一个更新,坑不少,没法当面交流,着实痛苦。好在我和一个兄弟(现在字节实习)执行力比较强,硬是在 ddl 前把项目肝了出来,为日后 996 打下了坚实基础。

在 Flutter 主要立足于移动端,Flutter Web 只是顺便做 web 的支持,所以 Flutter 是移动端布局思想,和 web 布局思想存在一些出入,上手会有一些误区。比如我们写惯了 div,到 Flutter 中会习惯性嵌套 Column,稍有不慎就会遇到如下场景:

  • Column 中嵌套 Column,内层 Column 有 Expanded,直接抛出异常
  • Scroll 类型组件中嵌套 Column,内层 Column 有 Expanded,直接抛出异常,报错和上面一致

阅读源码后发现原因都是:Flex 子元素的 flex 值非零但是外部传入的限制高度为无限,即 maxHight 无限大,所以 Flutter 无法确定元素到底为多高(RenderFlex children have non-zero flex but incoming height constraints are unbounded.),而这样的问题在 web 标准中可能出现,毕竟高度本就能无限延伸。解决的最好实践如下:

既然是可用空间无限导致问题,给定一个有限的 maxHight 值就 ok 了,甚至可以在内层 Column 中使用 mainAxisSize: MainAxisSize.min 配合 Flexible(这样虽然可以但是多此一举,没必要,但有助于理解)。

Flutter 的布局其实比 web 更简单直接,万物皆可 Column 与 Row,这两个 Flex 类型组件将屏幕方方正正划分,其中 Column 组件让人又爱又恨,首先它让垂直方向的高度不再像 web 中那么难以控制,如果你在根组件中直接使用 Column 做最外层容器,它的默认高度就是屏幕高度,子组件又有 Expanded 能划分剩余空间。web 中想对高度精确控制还要 html,body 都来个 height:100%,每层组件自己定高,要划分高度不得不计算百分比。本质上因为 web 认为:文本水平方向排布,而元素从上到下堆砌,最终高度是所有元素换行后自然堆叠形成,人为控制垂直方向的高度不是优先选项。而 Flutter 加强了布局的规范,认为水平和垂直方向的布局都是同等重要的。所以不建议用 Flutter 开发 web 为主的项目,web 网页应该作为 Flutter 开发 app 的附属产物。

Flutter 相关收获这里只是做一些总结,后续会结合代码更详细的总结成专门的文章。

Webpack 一发入魂

二月中旬通过的淘宝提前批,硬生生到四月底才定下 offer,终于五月入职开始“快乐工作”。很幸运,第一个项目就是优化内部的一个庞大中台系统,其规模在集团内部也难得一见。大项目的问题很明了,就是体积和打包速度,但是真做起来一时间还不好入手,知道要进行代码分割,但是上手配置起 webpack,就出现了各种无法掌控的打包结果,有时甚至把体积优化得更大。

于是只能先好好学 webpack 的基本配置,但是官网教程把属性分开讲解,很细碎,没办法统一理解,有的时候光看一个属性的描述是吃不透的,而网上的实例教程也都是按着官网路子,一个实例讲一个属性,缺乏一个渐进式的实例来讲解整个 webpack 的优化配置。经过一段时间的沉淀和摸索,我把 webpack 优化的坑踩了一遍,并且阅读了部分源码,终于有了比较完整的认知,成功将项目性能提升了一截。

踩坑的过程痛苦而充实,完成项目优化后,我决定自己撸一个渐进式的实例,把整个 webpack 代码分割体系讲解一遍,让读者能真正一个实例搞懂代码分割,最终产出此文:在淘宝优化了一个大型项目,分享一些干货(代码实例,图文结合)。紧接着深入源码进行分析,产出一文妈妈再也不用担心我的优化| Webpack 系列(二):SplitChunksPlugin 源码讲解

推荐入门同学读一读《深入浅出 Webpack》,虽然这本书只有 Webpack3 的内容,但是依然是入门的最佳倚仗,至于如何玩转 webpack4 以后的代码分割,建议仔细阅读我总结的文章,一定会有收获。

React 拨乱反正

我开始正式使用 React Hooks,以前仅仅了解 hooks 的特性,停留在 demo 阶段,并且为了帮助理解我把 React 函数组件和类组件进行类比,然而在实际开发中,我发现一些类比让我对函数组件有了错误认知。

我把 useRef 和类组件的实例属性(this.xxx)类比,这没什么问题,但是我又把 useState 和 this.state 类比,就有问题了。函数组件的状态是通过变量从钩子空间中取的(let stateA = useEffect(1)在每次重新渲染时执行),每次重新渲染都会执行一次函数组件,每次执行都会重新声明一次状态变量,而非在同一个变量上修改 ,这是和类组件截然不同的特性(类组件状态永远在一个 state 对象里改,每次重新渲染不会重新声明 state 对象),这样的特性遇到闭包会埋下隐患,比如这种情况下的闭包:

export const funComponent = (props) => {
  const [stateA, setstateA] = useState(1);

  useEffect(() => {
    window.addEventListener("click", () => {
      console.log(stateA);
    });
  }, []);

  return (
    <div
      onClick={() => {
        setstateA(100);
      }}
    >
      改变stateA的值
    </div>
  );
};

window 上的 click 只在函数组件第一次执行时进行了绑定,使用了 stateA,这个 stateA 值为 1,而之后我们点击 div 改变 stateA 的值为 100,然后再触发 window 的 click 事件,发现无论如何打印的 stateA 都是 1,并不是 100,这是因为在 window 上绑定 click 时,引用的 stateA 为 1,之后重新渲染再次声明的 stateA 虽然变为了 100,但是 window 的 click 回调函数一直保留着对 1 的引用,所以 1 并不会被回收,而是一直被事件回调使用。

总结一下,函数组件和类组件的思维是不同的,一个是函数式编程思想,另一个是面向对象思想,所以内部原理也有所不同。建议新人理解 React 两种组件时,不要过度类比,而是将函数组件和类组件分开理解,从结果出发:既然它们最终都是返回一个 React 元素,那么思考一下他们是怎么用不同方式达到最终的渲染结果的。

最后抛出一个问题,供自己和感兴趣的读者思考:React中(也可以上升到其他领域),大家为什么更偏爱函数式写法?

前端天花板低?

春招期间,身边一位曾在蚂蚁实习的同学从前端转向后端了,和我刚好相反。“感觉后端天花板更高,想去试试”,他的理由没有问题,甚至很有道理。放眼 IT 世界,后端技术沉淀已经足够深厚,而前端东西虽然五彩缤纷,但需求细碎,在技术深度上的确不如后端,看起来各路大厂也是后端技术专家比例高。前几年,是前端高速扩张的时期,前端缺人,门槛低,大家纷纷涌入,而最近这段时间,社区上有很多声音感觉门槛一下子高了,路一下走窄了,反映到实际就是大厂团队招人趋于“精英”化,社招只要能带队的技术专家。

前端的确开始进入深水区了,不过天花板低的定义并不全对,首先前端沉淀的时间就远远不如其他类别,很多地方等着人去开拓,现在就扣一个“上限低的帽子”,有点“莫欺少年穷”的味道;其次,一个行业,有失业,就有抱怨,有抱怨,就会形成一种“这行业不行”的言论,现在前端不再是拼人力体力,而是转向智力产出,曾经大批涌入的朋友中,会有一些遭受裁员,虽然同情他们的遭遇,但是从市场角度来看,这是一个行业趋于成熟的标志,对人才的评估和定义有了明确的考核标准,反而是前端地位提高的标志;最后,“上限低”有时是一种错觉或者说理解不到位,前端门槛低,摆个按钮改个颜色就算会前端,于是会一点前端的人很多,会给旁人造成前端技术太浅,做不了大事的错觉,其实前端还是有很多东西可做的,比如淘系的飞冰,蚂蚁的 AntV 系列和 Antd,社区上的各种框架、Webpack、Web IDE、Flutter 等等这些提高产能的工具,前端贴近业务,理解深刻后,用技术创造价值的机会是很大的,有句话说的好:有痛点就有价值,那么前端朋友可以问问自己,平时搞开发是不是有遇到很多值得吐槽的地方?价值说不定就藏在这些地方。

其实,天花板低的不是前端,而是增删改查的重复性工作,上限高的不是某个领域,而是你本人善于思考,创造价值的能力,正所谓三百六十行,行行出状元,没有菜的英雄,只有菜的玩家。干着重复性的劳动而不尝试突破,得到的收获永远不多,扮演的角色也能被轻易替代。所以希望朋友们干一行爱一行,进而尝试做好做精,而非因为社区内一些出于个人的片面定义就打了退堂鼓,失去了继续做下去的信心,有时可以换个角度:前端天花板低,那么为什么不由我们来将它提高呢?以后听到“前端不咋地”类似言论,不用纠结,也没必要回怼,继续做出点东西才是硬道理。

说了这么多,浓浓的鸡汤味。我还有诸多需要学习补强的地方,但会不断用自己的鸡汤提醒自己,脚踏实地学习,富有活力做事,最后竭尽全力创新。做到这些很难,但是不敢去做就更不可能了。有时候喝的鸡汤多了会反胃,恨不得毒鸡汤怼回去,但是无论如何还是要继续工作生活,多点正能量,少点偏见,别把路走窄了。

最后

这半年做了挺多事,认识了很多朋友,接下来要继续重构我的项目了,重构是个痛苦而必要的过程,希望能从中学到更多,回头继续分享。

下半年,自己再接再厉,也祝愿世界赶快脱离疫情。

掘金征文 | 2020 与我的年中总结 征文活动正在进行中......