写给母校UESTCweb开发方向的同学,也分享给大家,希望多提好的意见,沟通交流。
博客原文链接:http://leuisken.github.io/2015/07/17/web-dev/ 转载请注明出处
一、首先要知道的
如今我们使用的互联网,客户端与服务器端的交互无时无刻不在发生。比如我们在浏览器打开网页,浏览器就是客户端,将网页数据发过来的也就是服务器。其实服务器,并没有什么特别的,也就是一台昼夜不停运转的电脑罢了。每一台入网的机器,都会被分配一个ip,我们可以通过ipconfig / ifconfig这样的命令,知道我们电脑的ip地址。服务器本身,运行着服务器程序,他们监听着来源于网络的请求,并对请求进行响应。
比较常见的服务器程序,比如apache / Nginx / IIS等等,我们可以通过以下这样的一个小的实验,来了解网络中的客户端与服务器,是如何进行交互的。
实验:一个小的局域网
第一步:运行你电脑上的服务器程序(以apache为例,建议使用xampp / wamp这样的软件包,win下一键安装,能省不少事。当然,喜欢折腾的同学和SA们肯定要一个一个装啦),在apache的www目录下放入一些网页文件,然后在浏览器的localhost下浏览网页。
第二步:在电脑上打开wifi共享软件,通过ipconfig / ifconfig命令查看本机在内网的ip,让手机连接电脑共享的wifi(或者是两者同连一个路由器的wifi),在手机浏览器的地址栏输入电脑的ip,进入电脑的服务器并浏览网页。
上面的小实验的第二步,就模拟了一个简单的浏览器+服务器系统(BS系统),也在一定程度上反映了网站基本的访问原理。同时,这也是Web前端开发中真机测试移动端页面的一个行之有效的方法;当然,你也可以通过这种方式,实现局域网络的文件共享。
继续深入一步,我们在浏览网站的时候很少使用ip直接访问的,而是用www.baidu.com这样的域名,域名与提供对应服务的服务器的ip地址通过DNS服务器相互对应。我们可以通过ping命令,也可以通过一些在线的工具,如http://ping.chinaz.com来获取一个网站的ip地址,有时候ping出来的ip是不一样的,一般和你使用网络的地点有关,这主要是为了将对服务器的请求分流,减轻服务器的压力,保证网站的访问速度(比如可以了解一下CDN)。
二、开发的过程与设计的艺术
如何从0建立一个网站,这就涉及到软件产品的开发了。一般,会有以下几个职位。产品(PM):负责对软件产品的功能,目标用户等许多部分,进行一个详细的归纳整理,包括前期的功能地位和后期的功能修缮;设计(UE):对用户使用的产品界面、交互方式进行统筹和设计;前端(FE):活跃于客户端的程序员,负责使用代码实现设计师的设计,并与后端协调数据在客户端的渲染工作;后端(BE):活跃于服务器端的程序员,为前端的渲染提供所需的数据;系统(SA):保证开发过程中,对于服务器权限的管理与协调,以及服务器运行环境的提供,同时保证网站在生产环境中的平稳运行。
限于个人能力,我在此仅从前端和后端这两个角度,探讨网站实现的技术细节,其中会涉及许多具体的解决方案,供大家参考。
现在我们从这样的角度去看一个网站,我将他分为三层,视图层,数据层,以及控制数据在视图上的显示方式的控制器。举个例子,一个留言板,他的数据层会包括留言者的留言内容、留言时间、留言者的信息等内容。这些数据,就像一张excel表格一样,存储在我们的服务器。而我们的用户肯定不希望看到一个简陋的表格,他们希望看到的至少是一个界面,数据内容被清新美观的显示在我们的浏览器上,而这个界面,也会随着数据内容的增删修改而做出相应的调整。存储表格数据的,就是数据层;用户看到的,就是视图层;让界面随数据产生改变,则是控制器的使命。
现在,从技术的角度我们去实现他。首先,前端工程师根据设计师的设计,做出视图层的模板,后端工程师也做好相应的数据存储工作,包括设计创建数据库、数据表等等。现在,基本的工作完成。继续下去,我们则有很多的选择。
选择一:后端渲染数据到视图。
这种方法,就是前端将模板交给后端,告诉后端具体在哪个位置放什么样的数据,放的时候有什么具体的要求,剩下的渲染工作完全交给后端处理。这样的方法实现起来门槛低,而且由于服务器计算性能一般情况下强于客户机,后端来刷模板简单粗暴速度快,没有任何争议。缺点是后端工程师由于处理了数据填写的工作,相当于涉及了视图层(即前端)的工作内容,导致分工不够明确;同时,由于是后端更新数据,而后端代码是运行在服务器上的,每次要更新都要刷新页面重新请求一个完整的页面,某种意义上来说,用户体验相对较差。
选择二:后端将数据生成为小的数据文件,前端获取数据并由前端更新视图。
这种方法,涉及到前端的Ajax。说白了就是在后台异步加载另外一个页面,在加载过程中用户不会看到任何变化,而加载完成后,相当于在前端程序里获取了一个字符串,剩下的任务就是将这个字符串解析取出里面的数据并将对应内容渲染到相应的位置上。通过这种方式,首先可以保证视图层显示的内容都完全由前端工程师负责,分工明确,实现了一定程度上的前后端分离;同时,与服务器交互的文件大小,从一整个页面缩小到了一个仅仅包含要更新的数据的小文件,交互的量减小,带来性能上的提升;另外,由于交互文件一般使用json这种多数编程语言都可以解析的数据格式,不仅可以给网页前端使用,也可以给移动端app的前端开发使用,统一了接口,扩展时减小了工作量。
选择三:单页应用(SPA)
我先解释一下单页应用,和传统网站相比,他更接近于移动端应用程序,其核心就是将路由控制在前端工程师的手里。核心技术除了上面的Ajax,还有pushState,又有人将两者合称为PJAX。
先说什么是路由,路由可以理解为你网站域名后面的内容,比如www.abc.com/p/123这样的网址,后面的/p/123就标明了一个路径。可以类比于我们电脑的磁盘,当我在路径的位置输入C:/p/123的时候,我希望看到C盘下p文件夹下123文件夹的内容,当123变成了456,显示的内容应该有些变化。如果456文件夹存在,显示该文件夹的内容;如果不存在,则会弹出错误信息提示不存在。对应我们的网站,如果当/p/123变成/p/456的时候,也应该给出对应的显示。路由由前端控制的含义,就是说,网站url的变化与对应的显示由前端处理。你的整个网站实际上只有一个页面,前端根据url的变化,通过Ajax异步加载需要的数据,然后通过pushState操作浏览器的历史记录,达到与浏览普通网站同样的效果。
SPA最大的优点,大概就是响应速度了。当然,使用SPA对前端的技术提出了相对比较高的要求。使用SPA的一般情况,是你要做一个类似于安卓app的网站,如淘宝的手机站和Gmail,都是相当典型的SPA。不过,虽然现在SPA很多,并不是所有的场景都适合使用SPA的。
淘宝收藏夹的架构:
作为访问量如此高的网站,淘宝是怎么做的。(首先,php的后台肯定是担负不起这样的访问量的。)在淘宝UED,他们介绍了“中途岛”项目,基本架构是:前端工程师使用Node.js进行模板渲染,保证模板的渲染由服务器完成提高效率;Node.js访问由java后台封装的高级数据接口,而java在访问数据库的时候,则是使用C语言来实现最有效率的访问。技术细节可以参考淘宝UED的博客。
三、项目开发中值得一提的点
关于查阅资料和提问:
遇到问题先问搜索引擎,这我想应该都没有什么意见。用不了谷歌,可以从laod.cn下个hosts,翻出去的话,方法太多,不废话了。
当然了,找不到具体问题问人是不可避免的。但是当问题比较复杂的时候,比如前端这边处理浏览器兼容问题的时候,一定要有在线demo,一定要把问题描述的很清楚并且真的是自己解决不了了再问。关于提问的艺术,可以看看张鑫旭大神的博客(个人非常喜欢,强烈推荐前端同学关注),如何提问才能进阶成为前端大神?,这篇文章对提问需要注意的点说的非常明确,请大家,无论是不是做前端,最好都看看。
任务进度管理:
虽然在学校里做东西,很少会有严格的工期安排、进度计划这些,但是在公司里,这些问题肯定是会遇到的。推荐几个工具,大家可以了解一下:tower和微软的project。
版本控制:
几乎没有任何成功的软件项目,是一个敲代码敲出来的,况且,就算是一个人敲代码,也应该对自己所做的改动有所记录和备份。在这里,我将介绍两种使用git进行版本控制的方式,供大家参考。
分支管理:
整个项目是一个大的仓库,这个大的仓库由于不同的修改而有不同的分支。一般来说,有master(稳定发布版本) / dev(开发中的相对稳定版本) / 开发人员个人分支(集中个人的修改)这些。一般的工作过程为,个人会在个人的分支上修改,然后push到dev分支,稳定下来的dev分支作为新的版本再合并到master分支。那一部分出了问题,就在哪一部分进行修改。git在你每次更新分支的内容时都要求你输入一段描述修改的文字,这在将来的版本控制和回退上都会很有帮助。
仓库管理:
个人理解其实是扩大化的分支管理,项目负责人建立项目仓库,项目开发人员fork母仓库,做了自己的修改后,对母仓库发出pull request,申请合并到母仓库。这一方法最大的优点,就是方便负责人进行code review,保证代码质量;同时也可以方便对开发人员的贡献度进行考核。通常公司里会选取这种方式。
项目的持续集成:
持续集成大家在学校也很少会接触到,但是当你在公司里,遇到大项目的时候,就肯定会接触到持续集成这方面的需求和工具。个人认为持续集成更像是一种思想,在项目的开发过程中,前端和后端在开发过程中不断的对接,测试样例提前都做好,然后自动化构建项目,自动化测试等等。每当代码库更新(当然,本地构建失败的代码是不允许提交到仓库的)的时候,自动构建脚本、自动测试脚本都会跑出一个更新后的产品给大家看,方便团队中的每一个人掌握项目的情况和目前的进度。
实现这种思想,就需要与之配合的工具,关于持续集成这方面现在在企业中目前还没有“最佳实践”,不过确实有很多前人的经验供咱们借鉴。《持续集成最佳实践》里面对于持续集成实践进行了思考,欢迎点击。(感谢原作者高磊的无私分享。)
四、几点建议
在学习开发技术的过程中,个人给大家一点建议:
前期初学的时候,千万不要求多
道理大家都明白,什么都想学肯定什么都学不好。如果一个人都能学过来,那么我们还搞这么多方向做什么。有些东西,当你需要的时候,自然就会接触到;而那个时候你再学,你肯定是在实际项目中遇到了什么问题。有问题导向的学习是非常有效率的,所以千万不要求多,稳住。
千万不要刚刚入门就觉得自己什么都会了
这是我经历过的阶段,当时被一位学长拉了回来,也是非常幸运。这个阶段你觉得自己清楚很多东西了,感觉只要查查资料自己什么都能解决。其实想一想,这么多人研究这个领域,你怎么可能马上就看透了他呢。每个领域,都有很多坑,每一个坑也都会有至少一个与之对应的解决方案,而处理项目和解决方案,是一条漫长的道路。知识是越学越细的,本来你以为前端只能写写页面,深入学习以后,你才会发现,js可以写机器人;可以调系统API做桌面应用;哪怕只是在写页面这部分也有着页面渲染时间、内存泄漏等各种各样的问题和与之对应的层出不穷的解决方案。所以,低调,前面的路还很长。
学到一定程度,可以多去看看
我们知道书本上的知识肯定不是最新的,技术在不断的发展。可能你现在用的书上的代码都已经过时到运行不了了。这个,其实很正常,毕竟做网络这方面,怎么可能光靠书来追踪技术呢。所以多去看吧,github,各种社区、论坛,线下的技术交流,这些可以给你带来最新鲜的养分。所以,世界这么大,出去多看看。
五、结语:
还记得在看松本行泓的《代码的未来》的时候,里面提到的程序员“无所不能”的自由给我留下了很深的印象。写代码,按照自己的意愿去构建一个产品,一个项目,哪怕再小,依然是自由的。哪怕是在实现别人的需求,可以做好,做精,做出一套最佳的解决方案(没有最佳,只有最适合项目),给别人留下轮子去做好二次开发,依然是自由的,是有意义的。
其实个人觉得,单纯作为新人入门的话,本文的第三部分并没有太大的意义。之所以提及,是希望新人们能够更注重代码之外的效率,从团队合作、项目管理、利于维护和二次开发的角度去反思自己的代码,自己的解决方案,有时候会有更多收获。于是多加一笔,虽然限于个人水平,说的不详细,但也希望抛砖引玉,对大家能有些帮助。