原载于我的独立博客: https://lutaonan.com/blog/to-frontend-prejudicers
V2EX 这两天有一篇这样的帖子:《说句实话,我后端现在已经看不懂前端了,太难了》
原文内容是:
看不懂惹,肿么办,最近在学 react,完全抓瞎。
然后又附加了内容:
一直用的 jquery,手动找位置然后对应 dom 操作,现在各种前端各种依赖,一会 route 一会 webpack 的 给爷整蒙了都。
类似这样的帖子多年来数不胜数,但这次评论区的评论比较典型,所以我决定这次不再沉默。当然,本文并非针对帖子作者。
对于那些抱怨前端「看不懂」的网友,我们应该问他们一个问题:为什么前端就应该是谁都能看懂?
这些网友从来不会抱怨别的领域的代码看不懂,比如他们不会说「我一个前端已经看不懂后端了」,或者「我一个后端已经看不懂 iOS 」了。
所以在这些网友心中,前端代码就是要谁都看得懂才是正常的。因为谁都应该看得懂 HTML, 谁都看得懂 CSS.
显然,这群人对前端的认知还活在过去,他们一边享受着用 Web 技术做出来应用,一边意淫着这些包含复杂业务逻辑的 Web 应用靠 HTML 和 Vanilla JS (原生 JS) 就能写成。
换句话说,这群人最大的问题在于,他们意识不到 GUI 开发 (Graphic User Interface Programming) 是一个从图形界面被发明开始就一直在被研究的独立领域,而 Web 前端只是 GUI 开发的其中一个分支而已。
这群人没有意识到到底什么是「前端」。前端就是写 HTML / JavaScript / CSS 吗?不,前端应该泛指那些需要编写 GUI 的技术。在我看来,写 iOS / Android 应用和写 Web 前端没有本质上的区别,区别只是语言和平台,背后处理的问题是一模一样的:如何实现视觉和交互 -> 交互如何触发逻辑 -> 逻辑如何影响视觉的变化。
所以,如果认为浏览器识别的是 HTML 所以认为前端应该谁都能看懂、门槛低,进而得出前端目前的工作流是问题复杂化的结果,就如同因为 Android 的 UI 是用 XML 写的就认为 Android 门槛低一样不成立得可笑。
对 GUI 开发难点的不了解是导致这种误解的最主要原因,以网友「 avastms 」提出的评论为典型:
这是前端圈长期逆淘汰的结果。
模板混代码里这种 PHP 宗教行为就别提了。
个人认为因为 javascript 语言的部分原因,前端很少有人懂什么是继承,什么是类,实例到底啥意思,更别谈良好维护引用了。
什么 redux,什么 vuex 根本就是莫名其妙,不就是事件监听吗,像 Node.js 那样 EventEmitter 多么清晰,非得自己造概念。
画虎不成反类犬,凡是有这套什么状态管理逻辑的,代码完全不可读。
前端自己也是不争气,不用别人的这些狗概念,自己就不会写代码了吗?
没有什么 redux,自己就不会管理自己的属性了吗?
他说:「模板混代码里这种 PHP 宗教行为就别提了」,想必他在说 JSX. JSX 刚开始出来就充满争议,但人们最终会发现,JSX 是函数式 GUI 开发最易读写的方案。实际上,他完全可以选择不使用 JSX,这样去写代码:
const Component = h(‘div’, null, [h(‘p’, null, ‘hello world’), h(‘p’, null, ‘I am Randy’)])
但是,这位网友大概更愿意读这样的代码:
const Component = (
<div>
<p>hello world</p>
<p>I am Randy</p>
</div>
)
觉得这样的写法恶心,多数是因为不知道 JSX 这个语法糖的背后是什么。
事实上没有人阻止任何人不用 JSX, 或者看看 Flutter 就大概知道没有 JSX 的 React 会是什么样子。
作为补充,这是希望 Flutter 引入 JSX 的相关讨论:Consider JSX-like as React Native · Issue #15922 · flutter/flutter · GitHub
至于提到的 Redux 和 Vuex, 证明这位网友根本不知道 EventEmitter 和 Reactive 的区别。这里就不展开讨论了。
为什么我们宁愿用 JSX 这种折中方案也不愿意放弃函数式编程,是因为声明式(Declarative) 是编写 GUI 最好的方法。复杂的 GUI 应用包含复杂的状态,人脑在处理复杂的状态绝对不比计算机在行,我们尽可能地把这些状态交给计算机做,函数式编程就是我们实现这个目标的工具。
Elm 的作者写过一篇名叫 Concurrent FRP 的论文,讲述了函数式响应式编程 (Functional Reactive Programming) 在 GUI 开发中的历史背景和应用。
那些喜欢说「 jQuery 一把梭」的网友,要么遇到的业务很简单,要么是在自虐。我见过写外挂用易语言一把梭的,但没听说过 Adobe 写 PhotoShop 用 Visual Basic 一把梭。
有些人,能接受 Maven, Gradle 的不完美,也知道什么场景应该用什么技术栈,但一旦开始写点前端代码,就认为应该有一个神一样的、完美的、还没有学习成本的构建工具,然后 Twitter, V2EX 抱怨一番,却不愿意认真学一学前端这个领域的知识。
不要妄想有一个睡醒就突然会用的构建工具。说实话,Webpack 不需要任何配置就能用,再不行试试号称 zero configuration (零配置) 的 Parcel, 用 TypeScript, 引入 CSS / LESS / SASS 通通不需要配置,跑起来就行。但那又如何呢,那些不愿意学习又想出活的网友们不懂的不是运行 webpack dev
这个命令,而是根本不懂这个命令背后解决的是什么问题。
一个人要锤子锤个钉子,结果大家都说雷神的锤子很牛逼。这个人听了,上来就要用雷神的锤子,结果拿都拿不起来。然后网上发个贴:「根本不懂为什么雷神要搞个这么重的锤子,给爷整蒙了都」。底下评论:「我工具锤一把梭!」楼下再附和:「雷神搞这个锤就是为了装逼」。
奉劝各位,把抱怨转化成求知,没有一个领域是不需要学习成本的,不管是做技术还是技术以外的领域,是分工和市场经济让各位觉得一切理所当然,然而像磨刀这样看上去简单的动作,也不是每个人都能磨好一把刀。
201
coloz 2020-01-08 23:25:28 +08:00
三流嵌入式开发,正在兼职做 ng 前端,觉得做后台更难。
实际项目中,前端工作只要达到“正常、能用”就行了,快 100ms 对用户没任何意义,遇到很多前端喜欢扯性能、框架,其实做起项目来还是实现需求了事,最后的原因差不多概括为:“项目是老板的,时间是自己的”。 但后台开发,性能和安全性是基本要求,这两点真要做好,就已经是很高的要求了。 |
202
diggerdu 2020-01-09 02:53:20 +08:00 via iPhone
|
203
rooob1 2020-01-09 08:31:07 +08:00
我想知道现在前端这么骚,遇到不支持 js 的客户端,怎么玩
|
204
FaiChou 2020-01-09 09:11:45 +08:00
@nfyig #91
贴一个今早老大发的文章. 用 js 实现上图中需求, 可能需要 `redux-saga` 中的 `race/take` 等 effects. 下面是 clj 的实现, 用 core.async 来解决异步通讯问题 ```clj/cljs (require-macros '[clojure.core.async.macros :refer [go go-loop]]) (require '[cljs.core.async :refer [promise-chan chan timeout mult <! >!]]) ;; 模拟关灯, 读取不成功时执行关灯操作 (defn- mock-light-off [] (print "关灯!!!")) ;; 模拟读取情况, 随机 2000 毫秒返回模拟消息 (defn- mock-read [c] (go (do (<! (timeout (rand-int 2000))) (>! c "[msg head....]")))) ;; 模拟生成消息, 60ms 之内,随机时间, 消息内容为 '-' (defn- mock-msg [c] (go (do (<! (timeout (rand-int 55))) (>! c "-")))) ;; 后续消息读取, 50ms 读不到就结束,读到就增加到消息尾部, 然后继续读, 直到超时 (defn- mock-read-proceed [c v] (go (>! c v)) (go-loop [msg ""] (mock-msg c) (let [[v q] (alts! [c (timeout 50)])] (if (= c q) (do (println "读到消息:" v) (recur (str msg v))) (println "读取结束, 最终结果为:" msg))))) ;; 读取函数, 模拟 1000 秒超时 (defn scan-with-time-out [c] (mock-read c) (go (let [[v q] (alts! [c (timeout 1000)])] (if (= c q) (do (println "读到消息头:" v) (mock-read-proceed c v)) (do (println "首次读取超时,操作结束") (mock-light-off)))))) (let [c (chan)] (scan-with-time-out c)) ``` |
205
wxsm 2020-01-09 09:29:16 +08:00
牛逼的人一般都趋向于谦虚和理性,可见本站大多数用户能力不怎么样,还爱抛狠话。lz 的文章已经写得很中肯了。
|
206
yaphets666 2020-01-09 09:38:58 +08:00
@Felldeadbird 开发环境部署完毕后,还要学习多一套新语法 这句话是什么意思? 还有就是什么叫成品? 你指的成品是压缩后的代码? 前端也没什么开发环境啊 你把 nodejs 装上就行了. 最重要的一点,前端复杂不是前端想复杂,这些工具,语言的新特性,都是随着复杂多样的业务需求的出现而出现的,并不是前端开发人员想把简单问题复杂化.
|
208
StephenHe 2020-01-09 09:50:20 +08:00
看来大家年终奖都拿到手软
|
209
QuincyX 2020-01-09 10:22:15 +08:00
@rooob1 前端本来就是有很大差异化,暂时不要想着能用一套技术搞定 PC,mobile,web,Pad,IOT,AR/VR,嵌入式等等,但很快 js 就能运行在大部分平台上了
|
211
jss 2020-01-09 10:26:59 +08:00
啥前端后端,go+taro 一套带走...
|
212
yangguofu 2020-01-09 13:54:52 +08:00 1
“已经看不懂” 是以 “学过” 为前提的,结果过段时间学过的东西由于各种原因被取代不得不去学新的东西。
你要是能保证新学的东西 35 年后还能坚挺,我相信大部分后端还是愿意去学的,问题是抗不过一年。 所以才有 “jQuery 一把梭” 。 |
213
meeop 2020-01-09 14:20:34 +08:00
只能说现在前端的发展阶段,知识太多太杂太不系统了,导致对新人很不友好.
多数后端对前端的印象还停留在 html/css/js 三剑客阶段,本来我还能看懂前端,调试问题,修修改改的,你们这么一折腾就看不懂改不了了,这不坑爹呢么 等在发展一些,前端技术稳定下来有个明确学习框架,前后端交互有明确接口规范和调试工具了,后端就不会吐槽了 那时候的前后端交互就像现在微服务的不同业务之间接口调用,互相不需要不关心对方的实现,也不会有人吐槽你们服务内部怎么这么复杂我都看不懂之类 但是现在不行,业务方发现某页面有个 bug,一般报给后端,后端可能看来看去觉得是前端问题,但又不方便确定,再甩给前端,万一前端再甩锅什么的,确实体验不好 |
214
shintendo 2020-01-09 14:38:06 +08:00 1
@yangguofu
其实“取代”是个模糊的说法,如果 5 年前学的技术在 5 年后不能解决问题了,那不是技术变了,而是问题变了。说到底新技术提供的只是选项,如果你的问题还是老问题,那么你学过的老技术依然能解决,并没有浏览器不支持;如果你的问题是老技术无法解决或较难解决的,那么需要学习新的技术来解决也是理所当然的,并不是新技术的错,相反是新技术提供了解决的可能。 说到技术更新速度,娱乐圈尽管活跃,也没有传闻的一天一个新框架那么夸张,现在是 2020 年,react 是 2013 年的东西,vue 和 angular 是 2014 年的东西,webpack 是 2012 年的东西,都还如日中天,没有要被取代的迹象。 |
215
shintendo 2020-01-09 14:44:13 +08:00
@meeop bug 报给后端是有点奇怪的,我待过的公司都是报给前端,因为 bug 的直接表现是在页面上,让前端先看,比较方便确定是哪一边的问题
|
216
yammy 2020-01-09 14:59:27 +08:00
我寻思技术不就是拿来用的吗?什么技术又有什么关系,总有人喜欢比较,所有的技术都是一种思想而已,而价值观则由市场导向。难点不在于某种技术,而在于人,那些说某种技术简单或无用论的时候,都在体现他们那并不熟练的技术能力而已。因为每一种技术都有那渺渺的精英,他们主导着技术突破性的成长。
|
217
liuyitao811 2020-01-09 15:22:26 +08:00 via iPhone
作为主要负责前端工程的,那我也可以说我搞不懂现在的后端了,为什么要用微服务、docker、k8s 管理?为什么不单机部署?查日志用 grep 一把梭?为什么要信息队列和各种库解决一致性?
都是为了实际业务场景才存在的,事实上 80%的 web 页面都可以用 jquery 搞定的,但只有那少部分复杂的 web 项目能提供核心价值,在线文档、hybrid app 都是前端工程化的体现,只有前端工程才需要那些复杂的概念组织好架构 |
218
robinlovemaggie 2020-01-09 15:38:03 +08:00
jQuery 在 React 出现那一刻就已经退出了 dom 舞台~
|
219
easonl 2020-01-09 16:19:17 +08:00
各有所长,各有专攻。
前端技术发展太快了,less 和 hybird 框架 是很好的例子。 |
220
Mrl1u 2020-01-09 16:27:16 +08:00
不把前端搞复杂一点,前端玩家要因为后端开发死一大片。技术统一导致竞争激烈,又死一大片。问题是,后端看不懂,技术分类繁杂,意义在哪?
|
222
yangguofu 2020-01-09 18:08:30 +08:00
@shintendo
有时候你不得不去看别人用新技术写的代码,现在无论他们使用的新技术不是为了解决新问题,我掌握的老技术就已经 “不能用” 了。 |
223
laminux29 2020-01-10 00:41:51 +08:00
@lijunbo
1.我并不觉得有什么高人一等。很多东西,比如智力、学习能力、选择的方向等等,这些只是运气,只是概率而已。很多人能把后端学好,也只是投胎到一个比较好的智力与学习能力上,这没什么了不起。 2.不要妄自菲薄,每个人、每种学科,各有价值。离开前端,后端什么都不是。 3.虽然如此,但后端,客观来说,难度的确比前端大,但前端的复杂度却比后端强。 最后,没必要因为自己学什么而感到骄傲或沮丧,你学前端做到顶级大佬,仍然能在收入上秒掉一堆后端。 |
224
adoal 2020-01-10 01:47:03 +08:00 via iPhone
20 多年前就开始做桌面 GUI 的老人表示现在前端的工程化(某种意义上也就是一些人认为的复杂化)其实就是把桌面 GUI 工程化过程踩过的坑再踩一遍罢了。
但是跟当年桌面 GUI 的发展🈶️两点不一样 一是 web 前端由于历史进程原因颇有一些尴尬的技术限制,导致经常要额外绕路和填坑,于是更加复杂了。 二是当年桌面 GUI 是按部就班慢慢打磨着发展的,而 web 技术(不只是前端)托互联网行业风大能吹猪的福,难免发展糙快猛。 |
225
fuxkcsdn 2020-01-10 09:57:42 +08:00
不需要我修改配置的话,我们还可以是朋友
npm install 后看到一大堆警告和报错就浑身不舒服 |
226
codeDreamfy 2020-01-10 10:52:21 +08:00
做技术不能太局限和眼界狭隘,要想做架构师,那肯定前后端都要搞过的人才行,有这个时间去争辩,不然一起多花点时间去提升自己,作为某一端的开发不能存在优越感的想法,最好都有所敬重,最佩服那种虽然不会具体的,但是思想稍微一看就明白的人呢~
|
228
cassyfar 2020-01-10 16:36:38 +08:00
工作经验,呆过的公司,前端开发框架都非常成熟,有自己优化过的 react 和 jquery,甚至做 mobile 开发你可以直接用公司自己的 react 梭。前端的活真大多都是复制粘贴。
你们说前端可以做得很难,我不否定,就如同后端有些活,也很简单。但是大多数工作中前端的活,真的有点儿乏味了,基本不需要 system design。 |
229
charlie21 2020-01-14 14:45:43 +08:00
@cassyfar 也避免了垃圾的 system design。实际上 前端发展得快,正是因为技术负债很轻
https://www.infoq.cn/article/alibaba-freshhema-ddd-practice 内部大部分 java 代码都不属于 DDD 类型,有设计的也不多,更多的像“面条代码”,从端上一条线杀到数据库完成一个操作,仅有的一些设计集中在数据库上。我们依靠强大的测试保证了软件的外部质量(向苦逼的测试们致敬),而内部质量在紧张的项目周期中屡屡得不到重视,陷入日复一日的技术负债中。 - |
230
dabaibai 2021-10-28 10:02:18 +08:00
说真的 前端太杂了...
|