前端的技术、工具链实在太多,发展又快,简直有些疯狂。这里简要说一下项目中用到技术的一些评估和感受。

个人对某些技术的熟悉程度、理解程度不一样,所以我的感受跟他人的可能并不匹配,这个很正常。

TypeScript – 简称TS

如果你的项目使用的技术栈比较复杂,而你对TS熟悉程度不够,那么TS在早期将起到巨大的阻碍作用。尤其是开启了TS的严格模式之后。

在项目中后期,TS将对项目的质量起到巨大的提升作用,算是对前期各种头痛的一种补偿。

这里绝不是说使用TS不好,恰恰相反,TS非常的不错。但是TS带来的复杂性,特别是与各种框架混用带来的复杂性叠加,用户没遇到就很难预期。

最典型的就是各种泛型“满屏飞舞”,时不时的冒出来新的类型定义让人茫然无措 – 只有语言手册里面才能查的到。各种事件回调究竟应该怎么定义才能编译过去,如何让该死的lint程序闭嘴,都是让你十分恼火的事情。很多代码库都是javascript写的,并不是原生TS编写,让它们恰当的兼容并且正确运行,好多时候,并不简单。

光是这些玩意儿排雷,就够你忙活好多天的了,你啥也产出不了,整天困在TS这里。TS在这个时候,就是巨大的障碍。如果确实时间紧急,个人建议先别用TS了。或者,使用折中的办法:先关掉TS的”strict模式”,按手册修改tsconfig.json配置文件即可。”strict模式”下,TS把弱类型的js变成了强类型的js,完全没有弱类型语言编写的那些隐患,当然也就没有了弱类型语言的各种便利。

动态语言的优势之一就是弱类型编写方便,现在是一定要把弱类型转变成强类型,如此才觉得“安全可控”?我想起joel的说法:关键在测试充分,并不在语言是弱类型还是强类型。把书写方便的弱类型的js,强行弄成c++一样,是能查出一些问题来,可是写的人很累啊,兼容性差的框架更是烦死人。比如,前端页面的事件响应,你真的关心事件响应的具体类型么?为了通过编译,到处搜索查了半天定义,有意义么?我管它是什么类型,可以正确响应就足够了,这才是绝大多数情形。所以从这点上来说,TS过度使用,也是过犹不及的事,它把动态语言的优点抵消了。作为平衡,我建议关闭TS的strict开关。

Redux 本身已经很麻烦的了,你看下TS + Redux,还能整明白么,讲了大半天都是啥玩意儿?

https://redux-toolkit.js.org/usage/usage-with-typescript

延伸,可以看看这位老兄的吐槽:https://www.zhihu.com/question/273619114

……跟着文档撸了几百行Demo级别代码,确实感觉无缝接入,然而,你写东西得依赖框架吧?这个时候才是大坑,注意 TS没坑,框架没坑,TS+框架会有很多坑

你必须学习框架+全家桶的各种暴露出来的d.ts(还好用的是React,生态良好,生态差的在下一条出现),重新配置webpack,并解决各种冲突,比如在webpack中设置了src为@方便我们引入文件,然而Typescript不识别会报错,你需要解决这种冲突,此类冲突很多,还有如果TS彻底替代babel会出问题,比如不能享受babel-plugin-import这种按需引入的Babel插件了,最好的方法是TS+Babel,这又是额外的复杂度,再比如prettier美化插件,虽然支持了TS但是会出现各种各样的花式美化,还有各种各样的坑爹的地方就不提了,需要有一段很恶心的过程去一点点踩坑,我对那段的记忆反正是痛苦的……

感同身受。

Material-UI

简称:mui,UI框架库。它与React框架是很好的搭配。初次接触mui的用户,或者有过其它UI框架 – 特别是bootstrap框架使用经验的人,会觉得很不适应。它让人觉得莫名其妙,为什么一个个简单的HTML控件、标签,都包装成一个个的组件?Bootstrap框架就没这个问题,直接在HTML标签上,加一个“class”定义就解决问题了,简直没有比这个更容易的了。

mui使用起来跟React组件一个样,这有优点也有缺点。它默认使用“CSS-In-JS”模式编写样式,后面会提到。

优点是:控制力强大,几乎每个标签、控件都可以通过程序控制。它可以做成一致性非常好的应用,比如你可以把应用需要的UI元素做成重用的组件,反复使用就可以达到目标。而Bootstrap要做到这样,经常得反复复制粘贴代码,稍微改下就会造成UI体验的不一致。

缺点是:它太麻烦了!编写、调试这样的UI,时间耗费是Bootstrap的10倍以上。

这种组件式写法让人觉得非常的麻烦,连个按钮都要自己编程一番,本质又跟业务逻辑没什么关系,纯粹UI的活。另外,React组件中CSS的写法没有规范,弄的五花八门,各种理念、说法都有,乱七八糟,mui也面临一样的困扰,你得找出适合自己的方式。

它在项目早期,也是巨大的成本消耗,你也得理解那一套套的组件控制逻辑。Bootstrap是不用这样的。实际上,Vue + Bootstrap开发难度比React + Material-UI容易的多。

只有等到项目的中后期,你把所需的UI抽成必要的重用组件,调试开发成熟,它就会带来开发效率和质量的提升。

React

对React的总体感受,一图抵千言。使用它太麻烦了!不要因为别人吹捧就无脑选择支持,看情况具体判断一下。

React不是一个完整的解决方案, 而只是一个View,一个UI。这意味着,你要使用它创建项目,需要选择大量的配套组件,研究这些组件的使用方式,解决这些组件相互结合产生的五花八门的问题,有时候解决不了只能换一个试试。它在配套组件的使用模式上没有啥规范,自由竞争,都是在探索。以至于,你的这个React项目和下一个React项目使用的东西可能完全不一样,别人的项目跟你的还不一样。代码风格和使用习惯因人而异。光CSS的使用模式就有40多种,你看哪个顺眼就用哪个。这个给项目带来很大的成本和选择负担。

就光官方支持的路由模块都有多个版本,新版本和老版本还不兼容 – 就一个路由模块真有必要这么折腾么??

这个事儿,不要看网上鼓吹的那些内容,自己上手做一个一样需求的稍微大一点的程序,就能体验出不同和各自的优劣了。

React里面特麻烦的地方之一是表单处理。因为没有“双向绑定”等便捷的框架设定,导致需要写很多机械式的“get/set”代码,还需要编写onChang/onBlur等事件的代码。

手写的话,如果结合使用UI框架,一个Input要关联4种以上状态控制:值、错误状态、错误信息、提示信息。 再加上onChange/onBlur/onSubmit/onClick这些事件处理。这只是一个输入框而已,如果有10个呢?你可以想下复杂度。总之俩字:麻烦。有额外的组件包可以协助处理,减少这些“脚手架”,但是模式也是五花八门,各有各的问题。 可是,这些包如何与UI框架结合起来,又成了另外一个问题。

React 追求单向数据流和函数式的纯粹,这是它设计的出发点,也是一直坚持的。这么做说不上什么不对、不好,有它非常有优势的地方。

比如,React系统中,只要状态一致,渲染的视图就一样。这个也很好,给开发带来了很多可控、可靠的保证。

要吐槽的,主要是它作为前端框架目前的领头羊,一些设计充满了探索的味道,未必做出的抉择都是正确的

发展、变更是不可避免的,它从class-component -> functional-compnent,很多的思路、思想都在变化。用户用新的就得重来。

技术的起点决定了很多设计。比如MUI的组件都是“自定义控制 – 受控组件”的类型,这个深层原因应该就是React自己。React自己的V-DOM体系,本身就是“受控” – 映射的典型例子。所以控制是个习惯和理念需求,本身就没有“原生”的概念和想法。

推而广之,进一步的对CSS的控制,也是一类的思路延续。但是这次可能走过了事物的边界。

React技术栈,远远超过React自己那些知识。各种附加的组件、模块加起来,是非常庞大的,理解掌握是需要时间的。这也导致它的难度总体比较大。

CSS-IN-JS

这事儿争议很大,这就是我上面说的:未必设计正确的东西。国外开发者支持、反对的声音都很多。比较代表性的是下面一些文章:

https://robkendal.co.uk/blog/why-is-css-in-js-a-bad-or-good-idea

https://zendev.com/2017/09/11/css-in-js.html

https://www.freecodecamp.org/news/the-tradeoffs-of-css-in-js-bee5cf926fdb/

https://medium.com/dailyjs/what-is-actually-css-in-js-f2f529a2757

https://gomakethings.com/whats-wrong-with-css-in-js/

https://zhuanlan.zhihu.com/p/103522819

作为开发者,不能根据自己的习惯轻易拒绝新事物,这会错失很多的思想和机会。就这个“CSS-IN-JS”而言,我的看法是,作为一种解决方案,尽可能的少用,只用在最合理的地方 – 合理判定看经验和需求。

新技术很容易被滥用,然后人们发现苗头不对,再反思,改进。上面的文章,有一位作者剖析的是到位的,他对Web的基础结构和规律理解的很深刻。

他认为,CSS全局可用是特性,并不是BUG和问题。“CSS-In-JS”把它当成了问题,用js的思想去解决它,纯属误入歧途。固然这样做也能办到,能解决一些问题,可是这本质上没有认识到实际的规则。“用js的锤子去硬砸本该用CSS螺丝刀解决的螺丝”

这个评论我是赞同的。“css-in-js”的写法在一些地方是不错的,有用的,但是全盘使用这个,肯定是错误的。我看完各路大神激烈讨论后写的文章,结论就是:少用,只在合理的地方做。

Vue

Vue是很赞的前端框架,使用Vue轻松省力,多快好省的出活。要挑毛病,就是社区提供的组件还不如React多。我是赞成使用“双向绑定”技术的,没有这个,系统会产生一大堆的”setting”代码,都是脚手架一样的东西,实际没有多少意义。

我不认为,框架的“纯粹性”可以压过其它所有的需求。因为你追求“纯粹”,就不得不放弃本来很轻松就可以得到的选项,硬要按那个逻辑去发展,很累。让开发者省力,本身也是巨大的优点,时间成本就是金钱。

比如Vue的状态管理Store,出奇的简单,就是设置、读取,有什么问题么?很好用啊,没啥问题啊。你再看看React + Redux,为了它的“单向”、“纯粹”付出了多少复杂的成本和代价。

小团队、技术栈控制力一般的开发组织,选择Vue是非常正确的。它带来的快乐远大于开发的苦恼。如果让我挑选前端框架,我优先选择Vue,而不是React。少受点折磨的人生不更快乐么?

我希望Vue发展的再快再好些,有机会我也给它添砖加瓦。

Tachyons

这个是看别人的推介知道的一个CSS框架,它走的是Utility路线,就是类似Booststrap,给一堆扁平的预定义的class,从而改变组件元素的外观。这个可以作为其它框架的补充。

项目地址:http://tachyons.io/

这些小的定义经常可以给开发带来不少便利,值得看一下。

这里要批评的是,它的文档可谓是“坏文档”的典范,稀烂。我看100个人看这个文档都不一定有一个有兴趣尝试一下。难道大多数技术人员真不懂怎么写文档吗?

好的文档至少应该有:特性特色,安装使用 – 包括各种场景,具体用法的案例效果,不同技术组合的解决,常见问题解答等等。你可以看看它写了几个,绝大部分都是一抹黑,新手完全不知所云。

未完待续。。。

编程语言的类型系统并不是核心问题,不要迷信银弹
Apple公司的M1芯片和开源的RISC-V芯片给了我们什么启示?