如果你是个毫无基础又想要转岗成前端工程师的迷惘初学者,你脑中浮现的第一个问题有八成会是这个。接下来你会做什么?你大概会用:「如何成为前端工程师」、「前端 入门」、「前端 转岗」、「前端 非本科」等等的关键字来搜索,然后呢?
然后我希望你能搜索到我这一篇,让我来好好告诉你。
基于上一篇(如果你还没看过的话:跟着小明一起搞懂技术名词:MVC、SPA 与 SSR)的反应出乎意料的好,因此这次还是由小明出马,由一段虚构的故事慢慢带你看前端工程师到底需要会哪些东西,故事看完了,你也差不多知道你到底该学什么了。
这篇文章的目标是你没什么程序基础也能够看得懂,比上篇的门槛再低一点。故事情节的发展顺序不一定代表真实世界中这些技术出现的顺序,顺序的安排只是因为我觉得这样子能帮助初学者更好理解这些技术到底在干嘛。
好,让我们开始吧!
在很久很久以前…(真的很久)
那时候小明 12 岁,正在念小学六年级。在上电脑课玩着世纪帝国的时候(how do you turn this on?),老师突然宣布学校有举办班级网页设计比赛,优胜者可以获得十个好宝宝章。
身为一个从小学二年级就开始用电脑的人,小明自认为对电脑操作都很熟悉,心想网页应该也不难,就决定接受这个挑战。并且在回到家之后 ,上了奇摩知识+发问:
[急]请问要怎么写网页?求解20点
底下热心的网友们给了他两个关键字:FrontPage 跟 Dreamweaver,并且跟他说写网页其实很简单,这两个软件提供了很多现成的组件,你就想成是在打一份 word 文件就好,只是你可以加上按钮、表单等等只有网页会出现的东西。你只要用拖拉的方式,就能够很轻易地写出一个网页来。
就如下图所示,你可以立刻看到你的网页长什么样子:
图片来源:https://googlesystem.blogspot.com/2006/02/say-goodbye-to-frontpage-and-jeeves.html
图片来源:https://yepdownload.com/macromedia-dreamweaver
虽然搞不太懂是怎样一回事,但小明试用了一下这两套软件,发现写个网站还真的很容易!就跟编辑文件一样,你想要编辑什么文字你就直接改就对了,要图片的话也可以很轻松的直接插入。
一直到小明长大后才知道,原来这种编辑模式就叫做「所见即所得」,你看到编辑器里面长什么样子,实际上的网页就会长成那个样子(英文叫做 WYSIWYG,What You See Is What You Get)。
经过一番摸索之后,小明完成了班级网页的雏形:
他才小六,不要太苛责他
「才一个下午我就可以做成这样,再给我三天,我应该可以拿优胜吧」乐观的小明自觉前途一片光明,想说今天也累了便先去洗洗睡了。
他不知道的是,坎坷的未来正在等著他。
与网页,本人的初次见面
隔天放学回家,小明打开电脑想要继续做班级网页,可是却发现 FrontPage 怎么样都打不开,重开机、重新安装都没有用,就只差重装了。可是重装会把即时通的历史记录全部都洗掉,母汤母汤,到时候小美传给他的讯息就都不见了,这可不行。
束手无策的小明,看着昨天用 FrontPage 产生出来的 index.html,不知道哪来的灵感,对它点右键,选了「以记事本开启」,看到了惊人的画面:
这不是 Sublime,只是小明的记事本比较高级
「这是什么碗糕!」整个画面上,小明只看得懂中文,其他的根本不知道在写些什么。
原本小明想把窗口关掉,可是却转念想说再看一眼好了,而这一看却让他发现了一些规律:
<xxx>
似乎都是成双成对出现的,有<xxx>
就会有</xxx>
- style 看起来好像跟背景颜色之类的样式有关
观察到规律之后,小明心想那不然我来改改看,看会发生什么事情好了。于是他就把 <li>通讯录</li>
复制了几次并且改成其他文字,也把 body 那边的 background 换成 #666666。
接着保存,不用记事本而是用网页来打开,小明看到了下面的景象:
被小明手动更改过
「哇!居然还真的改了!」
一直到日后小明去书店翻书才知道,原来网页本人其实就是那个用记事本打开的文字档,而 FrontPage 在做的事不过就是自动帮你产生这些文字而已。而那些成双成对的<>我们叫它标签,不同标签有不同的用途。
举例来说,<li>
就是 list item 的意思,而标签里面放的就是你的内容。至于 style 则是人如其名,负责管理所有跟样式有关的操作,background 就是背景,color 就是文字颜色。
这些标签跟内容我们叫它 HTML(HyperText Markup Language),那些样式叫做 CSS(Cascading Style Sheets),这就是构成网页最基本的两大元素。
知道网页原来是由文字组成,不一定要用现成软件才可以写出来之后,小明便抛弃了 FrontPage,跑到书店买了几本网页入门的书,下定决心从基础学起。
不到半个月,他就已经可以只靠文字编辑器来写出整个网页。
我也想要华丽酷炫的功能
得意洋洋的小明觉得同年龄一定没有人像他这么认真参加这个比赛,看来要拿到第一名是轻而易举了。如此天真的小明,有天碰巧看见隔壁班的小华在请教电脑老师一些网页的问题,便凑上前去看。
不看还好,一看惊为天人,两千四百万人都惊呆了。
首先呢,网页上面有一个计数器,可以显示一共有多少访客曾经造访过这个问题。再来,你的鼠标附近会有一圈文字,鼠标移到哪里文字就跑到哪里,超级酷炫!还有网页跑马灯会不断轮播班级的公告,就跟实体的跑马灯效果一样。
意气风发的小明在那一刻哑口无言,深深觉得自己只是只井底之蛙,不知道外面的世界有多大。花了一些时间整了好自己的心态以后,小明鼓起勇气问了隔壁班的小华:「欸欸,你那些效果怎么用的,可以教我吗?」
『很简单啦,你去搜寻:网页开发百宝箱,那里真的是百宝箱,要什么有什么!根本就是网页设计师的哆拉 A 梦』
回到家以后小明照著做了,果真发现一片新天地,那裡充满著各式各样的酷炫功能跟效果,你只要把一段文字复制贴上到你的网页就能够起作用。小明选了几个自己觉得很帅的效果,改造了一下班网:
在此感謝一下网页建置百宝箱,尽管现在已经连不上了 QQ
可是,如果只是复制贴上的话,是赢不过小华的!必须要以这些特效为基础自己再定制化,才能够杀出重围,惊讶到学校的评审老师们。
秉持着这样子的决心,小明仔细看了一下贴到网页的那些文字,希望能发现一些端倪:
滑鼠移上去会动来动去的特效
虽然看不太懂是在做什么,但小明心想:「这应该就是写程序吧」,透过一些代码来操控 HTML 上面的元素,产生出会震动的图片的效果。
上网查了一些资料之后,小明才发现原来这个程序语言叫做 JavaScript,能够操纵网页上面的东西,只要是看得到的地方都可以用它来操作。所以理想上能做出任何你想得到的功能。
以上面的图片震动功能来说,就只是用 JavaScript 写了以下代码:
- 当鼠标移上图片的时候
- 开始震动(震动原理:不断改变它的位置)
- 当鼠标移开的时候,停止震动并恢复位置
知道原来可以用 JavaScript 做出这么酷炫的事情之后,没有理由不把这个学好。于是小明就到书店找了几本相关的书籍,从最基本的那些变量、迴圈、判断式开始学,希望有朝一日能够写出属于自己的程序。
过了两个礼拜,小明顺利的实作出以下功能:
- 封锁右键(原理:侦测到按下滑鼠右键时就刻意不做任何事)
- 显示日历(原理:靠代码抓出现在时间并显示出来)
- 显示欢迎文字(原理:网站载入完成时就跳出一个视窗)
而凭借着这些小明手写出来的功能,顺利获得了班网评审老师的一致赞赏,使得他拿到了班网比赛的第一名,把十个好宝宝章轻松纳入口袋。
原本就不谦虚的小明在夺冠之后变得更加狂妄,在即时通的状态写说:
哈!网页不过就这样嘛,就是 HTML 做内容,CSS 做样式,JavaScript 加程式码,只要会这三个就好,太简单了吧!
是的,其实网页一直到今天还是如此,依旧是以这三者为核心在发展。可是当原生的东西跟不上前端的演进的时候,我们就必须先依赖一些第三方的工具,才能帮助我们更有效率。
于是长大了以后
在拿到班网比赛冠军之后,小明就发现自己对网页设计真的很有兴趣,于是回家之后手里拿的再也不是 GBA,而是 Introduction to Algorithms,噢不对,是「第一次写网页就上手」、「100 个酷炫的 JavaScript 网页特效」等等的相关书籍。
升上初中之后,他依旧努力不懈,靠着课余时间进修网页设计,对网页三剑客(HTML、CSS 与 JavaScript)的掌握度也愈来愈高,自大的小明想说他应该已经是世界第一等的水准了,是该出去外面的世界闯闯,就跟父母说他想要尝试看看接案,拜托他们问问看朋友们有没有适合的案子。
把案子交给一个初中生跟交给一个专业的工作室,虽然前者的确也有可能很厉害没错,但从公司的角度来看,还是会倾向把项目交给后者,毕竟项目不单单只有「写代码」这件事情,还有开会讨论、报价等等的流程。
可是皇天不负苦心人,得来全不费工夫,终于在初中二年级的时候,小明接到了人生中第一个案子。
这案子是一个公司官方网站的开发,图片素材跟设计稿都由他们提供,小明只要负责把网页写出来就好,并且用 JavaScript 来实作一点特效。
小明虽然只是个 junior student,但自认为是 super junior,花了两个礼拜的时间就把版面切好,带到公司去跟对方 demo。案主起初相当满意,但却问了一个小明从未想过的问题:
你有在其他浏览器上面看过这个网站吗?旧版 IE、FireFox 或是 Safari?
没有,小明从来没有考虑到,他甚至连这世界上有这么多浏览器都不太清楚。而案主当场把他自信满满的作品用其他浏览器打开,第一个跑版、第二个跳出警告、第三个连画面都跑不出来,直接白画面显示 JavaScript Error。
这件事情对小明的影响很深,很深。
从那一刻开始,他才知道世界比他想像中的大很多。在自己的电脑上可以跑,不代表在别人的电脑上也可以跑。写网页不只是自己可以看就够了,也要保证其他人看到的能够跟你一样。
站在巨人的肩膀上
回到家针对不同浏览器测试之后,小明发现很多 CSS 跟代码都必须对不同的浏览器做出调整才行,例如说在 safari 上面,可能要加上特别的 prefix 才能够正常运行。
而 JavaScript 也是一样,不同浏览器可能会有不同的 function name,要针对每个浏览器写出不同的代码。
针对 CSS 的问题,小明发现只有几个属性要调整而已,很快就调好了,可是对 JavaScript,却发现这是一件极为麻烦的事情,有太多东西要加了,而且会把程式码变得非常混乱。
正在焦头烂额之际,有些已经在业界工作的网友跟他说:
你可以用 jQuery 啊!
得到了这个关键字之后,小明立马去研究这到底是个什么样的玩意儿。噢对了,如果你好奇他怎麽跟这些网友认识的话,他们是在程序设计俱乐部还有蓝色小舖认识的。
研究了两天之后,小明发现 jQuery 就是俗称的 Library,可是在这领域不会翻作图书馆,而是翻作「函数库」,意思就是它提供了很多现成的 function,你只要用就好了,不用知道他到底是怎么实际操作的。
这跟浏览器兼容性有什么关注呢?关系可大了,以前你要写 30 行代码去兼容不同的浏览器,现在你只要用一行代码,用 jQuery 提供的 function 就好,底层它都帮你做好兼容了。
除此之外,语法也变得比较简洁,一些常用的功能它都帮你先写好了。jQuery 的知名特徵就是 $ 这个符号,把一堆好用的 function 都放在这个裡面。
下图是 jQuery 与原生 JavaScript(又称为 vanilla js)的比较,站在巨人的肩膀上以后,可以少写很多行程序代码。
图片来源:http://youmightnotneedjquery.com/
顺利解决了浏览器兼容性的问题之后,案主也很开心的把这个案子结掉了。拥有了人生中第一笔收入的小明,从此以后开始了他的接案之路。
Don’t repeat yourself
随着案子越接越多,小明有一个非常困扰的问题,那就是 CSS。你知我知独眼龙也知,很多案主喜欢把需求改来改去,早上说网站主色是蓝色的好,下午说还是绿色吧,到了晚上又问说能不能改成红色试试看。
而且不只颜色,可能网页边距啦,宽度啦,总之要一直改来改去的实在是很麻烦,而且很多时候还会改错。
为什麽会改错呢?因为可能网页背景、按钮、文章背景都是用红色做为主色,所以最快的方法显然是把所有的 red 都取代掉。可是有些颜色虽然也是红色,但不是因为网页主色是红色,而是本来就应该是红色,例如说错误提示的文字。这种就必须再改回来,不然会变得很奇怪。
因此,小明都是这样改的:查找、替换,再把改错的改回来:
简易示范,使用 Recordit录制,诚心推荐这款 App
在改来改去的过程中,小明想起一句在这领域里面很有名的一句话:Don’t repeat yourself。不要一直做重复的事情,像现在这样就很不好,永远要屈就于这种非常不方便的流程。
有没有可能把程序的概念引入到 CSS里面去呢?例如说变量?这样我们就能够用变量来取代写死的颜色,要改的话也很方便,只要改一个地方就好:
JavaScript 的变量+ CSS
在业界工作的前辈们听到小明的想法之后,就跟他说了:
这不就是 CSS preprocessor 吗?
CSS preprocessor,翻成中文就叫做 CSS 「预处理器」,简单来说就是你可以先写一些不是 CSS 的语法,经过这个预处理器之后,就会变成符合标准的 CSS。
或是说得更白话一点,就是翻译啦,你先写中文,经过 Google 翻译之后翻成日文,然后日本人就看得懂了。差别在于 Google 翻译可能会翻的不精准,可是 CSS 预处理器能够翻的超级精准,保证是标准的 CSS。
有了预处理器之后,你就可以把变量也应用到 CSS 上面,或甚至你要用迴圈或是函数也可以!总之呢,有了预处理器之后,写 CSS 跟写程序的感觉变得更相似了,下面是个简单的范例:
图片来源:https://sass-lang.com/guide
最常用的预处理器有几个:SCSS/SASS、Less 跟 Stylus,语法都很类似,基本上挑一个学就够了,要转去其他的也不难。有了预处理器之后,就能够更有效率地去写 CSS。
但如果你不用预处理器,可以写网页吗?当然可以!只是业主要你一直改颜色的时候你可能会很崩溃而已。
还记得之前提过需要针对不同浏览器去调整 CSS 吗?有些必须要加 prefix 才能运作。这点用预处理器也能够很轻松地去解决,用一种叫做 mixin 的东西,你就想成是 function 就好:
图片来源:https://sass-lang.com/guide
原本在每个地方都要重复写这些不同的属性,现在把它包装成 mixin,你只要 include 进来就好。
不过,小明有了一个疑问:
既然我们都知道这个属性要加 prefix,为什么不让程序帮我们自动加上就好?
对啊,为什麽不?有个东西叫做 PostCSS,就是在做这件事情。(其实 PostCSS 包含了很多的 plugin,这边提到的是其中一个叫做 Autoprefixer 的 plugin)
在这边你要知道 PostCSS 跟 CSS preprocessor 的差别在哪,前者的 input 是 CSS,output 是加上了 prefix 之后的 CSS;后者的 input 是 SCSS(或其他),output 是 CSS。你甚至可以把两者合在一起用:
纯属范例,实际上 border-radius 基本上不用加 prefix
合在一起用的好处就是你在写 SCSS 的时候,完全不用管 prefix 这件事情,因为 PostCSS 都会帮你做好。
有了这两项神兵利器以后,小明在写 CSS 的时候就没什麽太大的问题了,就算案主们的需求朝令夕改,也能够凭凭借这些工具快速做出更动。而且长时间接案下来,已经累积了一套自己的程序代码,能够迅速就搭出一个基本的页面。
在不断接案的过程中,小明也就这样渐渐长大,转眼间已经是个大一新生了。小明成长了,前端的世界也慢慢在成长,长成一个小明从未预料到的模样。
像诗人依赖著月亮,像海豚依赖海洋
上了大学之后,小明开始挑战接更大的案子,而更大的案子就意味著不再只是那些美美的公司形象网站,而是开始往更複杂、更多功能的方向走,例如说购物网站或者是 CMS 系统等等。
身为一个程式设计师,当你看到一个没实作过的新功能时,第一件事情就是:上网去找有没有人实作过。如果已经有人把轮子造出来了,大多数时候没有必要自己重新做一个。
于是除了 jQuery 以外,小明开始用了其他的 Library 来解决问题,直接把别人写好的功能拿来用。可是用著用著,小明发现了一个问题,那就是引入 library 的机制。
现在的机制是怎样呢?就是直接引入每一个你要用的 library,然后直接用就行了:
用 script 标签引入
看起来其实挺合理的,但会有几个问题。
第一个,假如说 A.js 里面定义了一个变量叫做:VERSION,而 B.js 里面也定义了一个变量叫做 VERSION,那就会产生变数名称冲突,两个 library 互相干扰。
第二个,其实每个 library 本身也有可能使用到其他的 library,假设 A 用到了一个 library 叫做 popular,B 也用到了 popular,那我们这边其实就把 popular 引用了两次(因为 A 跟 B 都用到了,所以在引入 A 跟 B 的时候各引入一次)。
总之呢,污染全局变量跟 library 之间的相依问题让小明头很痛,怎么看都很不顺眼。在理想上,小明觉得这些 library 的使用应该要像其他程序语言那样,例如说 Python:
简易范例 Python 的 import
简单干净利落,要用什麽 library,就用 import 把你要用的东西引入进来,也可以在程序里面把 library 用不同的别名引入,或者是只引入特定的几个 function。
虽然能这样用一定很棒,可是 JavaScript 又不支持,怎麽办呢?
咦?有没有一种似曾相识的感觉?
如果 CSS 能用变量就好了,一定会很棒,可是 CSS 又不支持…
如果原生不支持,解法很简单嘛,我们就假装有支持,之后透过工具把它转成原生的程序代码就好了。像 SCSS 就是这样啊,反正转换完之后是原生的 CSS,一定有支持。
于是呢,一个可以让 JavaScript 支持这种引入机制的 Library 诞生了:
图片來源:http://browserify.org/
现在你可以直接在代码裡面写:var A = require(‘libraryA’) 去引入一个 library,而不是用 <script/>
标签去引入。而背后的原理就是靠着browserify 去帮你实作 require 这个函式,自动帮你处理好背后的相依性问题。
有了 require 的机制以后,在写 JavaScript 的时候你就可以分成好几个文件来写,最后再透过 browserify 把代码组装起来:
利用 require 引入想用的模块
最后透过 browserify,会产生一个 bundle.js,顾名思义,所有需要用到的东西都打包在里面了,这就是你真正需要在 HTML 裡面引入的档案。
这个要变、那个也要变,当我超级变变变?
虽然 browserify 成功解决了小明的问题,可是又有一个新的问题产生。截止目前为止,我们写 SCSS,接著用指令把 SCSS 转成 CSS。然后我们在 JavaScript 裡面开心用着模块,用 browserify 打包出 bundle.js。
尽管只是改一个小东西,就要打两个不同的命令去做转换,才能看到最后的结果。更别说要把这专案上线之前还要先对 CSS 以及 JavaScript 做混淆以及压缩,把程序代码变得更像乱码一些。
这些流程之后只会随著需求越来越烦琐,该怎麽办呢?可能过一年之后一个专案有十几个命令要执行,有没有什麽好用的工具能够处理这个呢?小明再次求助于认识的业界朋友们,最后得出了:Gulp 这个关键字。
Gulp 能够用代码来管理你的 workflow,你就定义很多 task,说清楚每一个 task 要做什麽事情,然后再去执行那个 task 就好了,如下图所示:
图片來源:https://gulpjs.com/
开头定义一个 task 叫做 html,是来把 pug 档案转换成 html,第二个 task 叫做 css,用 less 转换之后再 minify;第三个则是把 js 产生 sourcemap。只要你一打 gulp 这个指令,就会自动帮你执行上面三个 task。
有了 gulp 以后,当你拿到了一个陌生的专案,你直接去看 gulpfile.js 就可以知道这个专案应该要怎麽开始跑或是怎麽打包了,每一个 task 都清清楚楚写在裡面。
以前我们需要自己手动打好几个指令,现在我们用 gulp 转换成一个个 task,只要一行指令就可以又用 SCSS 转换成 CSS 又用 browserify 打包成 bundle.js,十分方便。
现在的小明已经不再是当年那个只会用 HTML、CSS 跟 JavaScript 写着班网的小明了,而是手上握有 SCSS、PostCSS、browserify、Gulp、jQuery 等等工具的小明。有了这麽多工具辅助,在开发网页的速度上面快了许多,因为每一个工具的目标本来就是让你变得更有效率,而不是拖累你。
就在此时,小明看到一个令人振奋的消息:新一代的 JavaScript 语法出来了(严格来讲是 ECMAScript),叫做 ES6,在这新语法裡面多了小明很期待的一些新功能。
不支持怎么办?你知道的 ??
既然是新语法,想必旧的浏览器不会支持。小明一路跟著前端发展过来,也大概摸清了前端的套路。什麽是前端的套路?
当你想用浏览器不支援的东西时,你就开发个工具来转换就对了
SCSS 如此,browserify 亦是如此。小明知道 ES6 推出时已经是第三手的消息了,因此他深知一定已经有人做出这个工具了,上网搜寻了一下,Bingo!
这个工具就叫做 babel,它的官方网站简单明瞭的说出了它的作用:
图片来源:https://babeljs.io/
简单来说就是你可以写新一代的 JavaScript(尽管浏览器还不支援),再透过 babel 把它 compile 成浏览器支持的语法。概念跟 CSS preprocesseor 有点像,但最大的差异在于 SCSS 的那些语法不是「下一代的 CSS」,所以浏览器以后也不会支持那些语法;而新一代的 JavaScript 只是「现在」还没被浏览器支持,有朝一日一定会的。
等到那天到来,你就可以把 babel 整个丢掉了,可是专案还是一样可以正常运行(但那一天可能要很久就是了)。
用了 babel 之后,就可以用一些又炫又潮的语法,只是你必须要多一层手续,用 babel 来 compile 才能在浏览器上面执行。不过没关係,因为我们有 gulp 了,所以只要在 gulp 裡面多增加一个 babel 的 task 就好了。
CSS 没问题了,JavaScript 也有了模块化以及新一代的语法,都已经这麽前卫了,难道还有什麽东西可以再进化吗?
靠北,还真的有。
你的资源,我全包了
前面提过了 browserify,让你可以用 require 把 JavaScript 引入进来使用。有人觉得单纯这样还不够,提出了一个疯狂的想法:
为什麽只有 JavaScript 呢?为什麽我不干脆把所有东西都视为资源?不只要引入 JavaScript,我也可以引入 CSS,甚至引入图片!
这样子一视同仁,把所有东西都视为是资源的想法,就是 webpack 的核心理念。我不只要 require(‘A.js’),我还要 require(‘style.css’), require(‘bg.png’)只要是外来的资源,我全部都要引入!
webpack 用起来其实跟 browserify 很像,差别在于前者把更多东西都视为是资源,所以写出来的代码会像这样:
把一堆东西视为资源
除此之外呢,webpack 也可以透过一个个的 plugin,在打包的时候对这些资源做一些事情。什麽事呢?例如说用 babel-plugin 把 ES6 转成 JavaScript!或者是用 scss-plugin 把 SCSS 程式码转成 CSS。
意思就是你在写 code 的时候,你甚至可以直接引入 style.scss,webpack 会自动帮你在引入时转换成 CSS!听起来很棒吧!
自从 webpack 崭露头角之后,browserify 就渐渐愈来愈少人用了,因为 webpack 可以做的事情又更多一些,而 gulp 的很多 task 其实也能被 webpack 取代(例如说 compile)。
但要注意的是 webpack 只是一个 module bundler,不是像 gulp 那种 task manager,其实你可以把两者配在一起使用,就像我们之前把 browserify 当作 gulp 的一个 task 一样,你也可以把 webpack 当作一个 task。
「呼,前端有了这麽多工具,应该很足够了吧!」小明边看著越来越多工具的专案边感叹著。
是的,工具差不多了,可是我们前面一直专注的都是在:新一代的语法跟模块化机制,完全忽略了前端变複杂以后最困难的问题之一。
如何让 UI 跟程序内部的状态同步?
如果你现在有个 Todo List 的 App,假设你的程序裡面有一个 array 叫做 todo_list,你这个 array 长什麽样子,你的介面就应该要长什麽样子,这样就叫做 UI 跟程式内部的状态同步。
难吗?乍看之下没那麽难,我们可以写出以下的程式码,在操作 todo 的时候同时操作 UI 以及内部的状态:
图片來源:https://ithelp.ithome.com.tw/articles/10188008
虽然在专案规模小的时候还行,可是如果你的专案超级无敌大,这就变成是一件很困难的事了,因为你要能永远保证这两者是同步的。照我们现在的方法,假如你有个 function 忘记更改状态,那你就 GG 了,之后的状态都不会再同步了。
Google 针对这个问题的解法是:那我自动让这两者绑定好了,改变 state 就会改变 UI,而改变 UI 的话也会改变 state,这样不就好了嘛!于是就有了 Angular 这套框架(我对 Angular 极度不熟,就只点到这了)。
而 Facebook 针对这个问题的解法非常非常非常直觉,真的非常直觉,是我认为从概念上最好理解、最简单的一个解法:
那就每次 state 改变的时候都重新渲染 UI 不就好了
你要删除 todo,你直接删除 state 的 todo,不用管网页上的元件。你要新增也是一样,完全不用管画面上的东西,因为只要 state 一改变,整个 UI 就会改变。以这个概念来实作的话,大概会变成这样:
图片來源:https://ithelp.ithome.com.tw/articles/10188008
有没有很简单?有吧!
要如何让 state 跟 UI 一致?写代码的人只要关注 state,每次都只改变 state,然后每改变一次就把整个 UI 按照现在的 state 重新画出来,不就能确保两者完全一样了吗?
听起来很有道理,那为什麽以前的人没想到呢?因为如果真的「每次都重画」,其实会有效能问题,因为事实上你只要重画一部分就好。但总之 React 解决了这个问题,让你用起来像是全部重画,实际上却是只重画必要的部份。
在学 React 以前,只希望你记得 React 的这个核心概念就好:只改变 state 就好,UI 就会自动跟著改变。
把这複杂的前端问题解决以后,小明对前端的掌握度又更高了一层。
初出茅庐
故事说到这,小明大学也毕了业,兵也当完了,退伍的隔一天便很兴奋地投了简历,过几天后拿到了人生中首次的面试机会。想当然尔,他投的职缺是前端工程师。
整个面试的过程都很不错,面试官很惊讶小明在这个年纪就能够对前端有这麽多的理解,而且该会的他都会了。在面试的尾声,面试官问了这个一句:「这麽多的工具,你不会觉得很烦吗?你都怎麽学会的?」
只见小明回道:
不会啊,出现问题不是就要解决吗?我也没特别学,就只是觉得用了这些工具能够解决我的问题罢了。
话说完,面试便结束了,而隔天下午小明就拿到了 offer。
「主管说你对程序的观念很好,催促我一定要快点发 offer 给你。」,HR 是这麽跟他说的。
结语
为什麽前端对新手来说这么复杂,这麽多工具要学?因为他们根本不知道前面发生这麽多事情阿,他们没有经历过这一段演变,怎麽知道为什麽要用这些工具?
工具的出现是为了把问题变得简单,而不是变得更複杂。当你发现引入了工具却让你变得更没效率,就应该好好思考你是不是根本不需要这个工具,而不是去怪工具不好用。
文章看完了,如果我写得还不错的话,你应该会理解 HTML、CSS、JavaScript、SCSS(CSS preprocessor)、PostCSS、jQuery、Gulp、Babel、Webpack、React 这些东西在干嘛,而这些就是现代一个前端工程师会需要的技能组(React 可换成 Angular 或 Vue)。
小明身为一个从以前就做前端做到现在的人,知道每一个工具出来时要解决的问题。但身为现今 2018 才想要踏进前端的你,自然而然就会觉得前端怎麽这麽多工具这麽複杂。但其实不是的,如果有人能跟你讲小明发生过什麽事,你应该就能对这些工具更了解。
为什麽、为什麽、为什麽!我一直再三强调你一定要常常问为什麽,你一定要知道为什麽这些工具会产生。当你知道背后的脉络时,就知道工具其实是在帮助你,而不是在阻碍你。就会知道这些工具的出现有其必要性,就能够更有个好理由去把这些工具给学好。
只希望这篇能帮助到一些初学者们更理解自己现在为什么要学这些工具。如果有任何错误的话也麻烦不吝指证,感谢。
原文链接:https://zhuanlan.zhihu.com/c_1152947740601491456