本文从属于笔者的Web 前端入门与最佳实践,2016年度版本在:2016-个人前端之路:工具化与工程化javascript
撰写本文的时候笔者阅读了如下文章,不可避免的会借鉴或者引用其中的一些观点与文字,如有冒犯,请随时告知。文列以下:html
前端的变革java
致咱们终将组件化的Webnode
我感受到的前端变化react
解读2015以前端篇:工业时代 野蛮发展webpack
若是你想进行WebAPP的学习,建议先看下个人编程之路:知识管理与知识体系相关内容
顺便推广下笔者总结的泛前端知识点纲要总结:Coder Essential之客户端知识索引(iOS/Android/Web) 、Coder Essential之编程语言学习知识点纲要、Coder Essential之编程语言语法特性概论github
几年前初入大学,才识编程的时候,崇尚的是一路向下,那个时候喜欢搞Windows、Linux底层相关的东西,以为那些作网页的太Low了。直到后来偶然的机会接触到HTML、JavaScript、CSS,很长一段时间以为这种这么不严谨的,毫无工程美学的搭配不过是诗余罢了。后来,深刻了,才发现,可以有幸在这片星辰大海里游荡,能够以几乎领先于其余方向的技术变革速度来感觉这个时代的脉动,是多么幸运的一件事。这是一个最坏的时代,由于一不当心就发现本身Out了;这也是一个最好的时代,咱们永远在前行。繁华渐欲,万马齐鸣!
借用苏宁前端结构师的总结,任何一个编程生态都会经历三个阶段,第一个是原始时期,因为须要在语言与基础的API上进行扩充,这个阶段会催生大量的Tools。第二个阶段,随着作的东西的复杂化,须要更多的组织,会引入大量的设计模式啊,架构模式的概念,这个阶段会催生大量的Frameworks。第三个阶段,随着需求的进一步复杂与团队的扩充,就进入了工程化的阶段,各种分层MVC,MVP,MVVM之类,可视化开发,自动化测试,团队协同系统。这个阶段会出现大量的小而美的Library。固然,笔者以Tools-Frameworks-Library只是想说明我我的感受的变化。
笔者从jQuery时代一路走来,经历了以BootStrap为表明的基于jQuery的插件式框架与CSS框架的兴起,到后面以Angular 1为表明的MVVM框架,以及到如今以React为表明的组件式框架的兴起。从最初的认为前端就是切页面,加上一些交互特效,到后面造成一个完整的webapp,整体的变革上,笔者觉得有如下几点:
移动优先与响应式开发
前端组件化与工程化的变革
从直接操做Dom节点转向以状态/数据流为中心
笔者在本文中的叙事方式是按照本身的认知过程,夹杂了大量我的主观的感觉,看看就好,不必定要当真,毕竟我菜。梳理来讲,有如下几条线:
交互角度的从PC端为中心到Mobile First
架构角度的从以DOM为中心到MVVM/MVP到以数据/状态为驱动。
工程角度的从随意化到模块化到组件化。
工具角度的从人工到Grunt/Gulp到Webpack/Browserify。
在正文以前,重要的事情说三遍,我是菜鸟!我是菜鸟!我是菜鸟!历来都没有最好的技术,而只有合适的技术与懂它的人。我感谢这些伟大的类库/框架,感恩它们的Contributor,给我呈现了一个何其广阔的世界。虽然2015的前端领域有点野蛮生长,可是也体现了前端一直是开源领域的扛鼎之处,但愿有一天我也能为它的繁荣作出本身的贡献。
如今H5已经成为了一个符号,基本上全部具备绚丽界面或者交互的Web界面,不管是PC仍是Mobile端,都被称为基于H5。笔者一直认为,H5技术的发展以及带来的一系列前端的变革,都离不开现代浏览器的发展与以IE为典型表明的老的浏览器的消逝。目前浏览器的市场分布能够由以下两个图:
浏览器分布图
国际浏览器分布图
这里顺嘴说下,若是想要明确某个属性是否可使用能够参考Can I Use。话说虽然微信内置的某X5内核浏览器连Flexbox都不支持,不过它帮咱们屏蔽了大量手机的底层差别,笔者仍是很是感恩的。固然了,在有了Webpack以后,用Flexbox不是问题,能够查看这嘎达。
2015年是JavaScript诞生的20周年。同时又是ES6标准落地的一年。ES6是迄今为止 ECMAScript标准最大的变革(若是不算上胎死腹中的ES4的话),带来了一系列令开发者兴奋的新特性。从目前es的进化速度来看,es后面应该会变成一个个的feature发布而不是像之前那样大版本号的方式,因此如今官方也在推荐 ES+年份这种叫法而不是 ES+版本。在ES2015中,笔者以为比较欣赏的特性以下,其余完整的特性介绍能够参考这篇文章ES6 Overview in 350 Bullet Points。
Module & Module Loader:ES2015中加入的原生模块机制支持可谓是意义最重大的feature了,且不说目前市面上五花八门的module/loader库,各类不一样实现机制互不兼容也就罢了(其实这也是很是大的问题),关键是那些模块定义/装载语法都丑到爆炸,可是这也是无奈之举,在没有语言级别的支持下,js只能作到这一步,正所谓巧妇难为无米之炊。ES2016中的Module机制借鉴自 CommonJS,同时又提供了更优雅的关键字及语法(虽然也存在一些问题)。
Class:准确来讲class关键字只是一个js里构造函数的语法糖而已,跟直接function写法无本质区别。只不过有了Class的原生支持后,js的面向对象机制有了更多的可能性,好比衍生的extends关键字(虽然也只是语法糖)。
Promise & Reflect API:Promise的诞生其实已经有几十年了,它被归入ES规范最大意义在于,它将市面上各类异步实现库的最佳实践都标准化了。至于Reflect API,它让js历史上第一次具有了元编程能力,这一特性足以让开发者们脑洞大开。
除此以外,ES2016的相关草案也已经肯定了一大部分其余new features。这里提两个我比较感兴趣的new feature:
async/await:协程。ES2016中 async/await 实际是对Generator&Promise的上层封装,几乎同步的写法写异步比Promise更优雅更简单,很是值得期待。
decorator:装饰器,其实等同于Java里面的注解。注解机制对于大型应用的开发的做用想必不用我过多赘述了。用过的同窗都说好。
更让人兴奋的是,JavaScript慢慢再也不局限于前端开发中,NodeJs的提出让人们感觉到了利用JavaScript进行全栈开发的能力,今后大大提升了开发的效率(至少不用多学习一门语言)。JavaScript在物联网中的应用也曾经引发一些追捧与风潮,不过今年物联网社区更加冷静地看待着这个问题,可是并不影响各大厂商对于JavaScript的支持,能够参阅javascript-beyond-the-web-in-2015这篇文章。笔者仍是很看好JavaScript在其余领域继续大放异彩,毕竟ECMAScript 6,7已是如此的优秀。
WebAssembly 选择了跟ES2015在同一天发布,其项目领头人是大名鼎鼎的js之父Brendan Eich。WebAssembly旨在解决js做为解释性语言的先天性能缺陷,试图经过在浏览器底层加入编译机制从而提升js性能。WebAssembly所作的正是为Web打造一套专用的字节码,这项标准在将来应用场景多是这样的:
开发应用,但使用任何一门可被编译为WebAssembly的语言编写源代码。
用编译器将源代码转换为WebAssembly字节码,也可按需转换为汇编代码。
在浏览器中加载字节码并运行。
须要注意的是,WebAssembly不会替代JavaScript。愈来愈多的语言和平台想在Web上大展手脚,这会迫使JavaScript和浏览器厂商不得不加快步伐来补充缺失的功能,其中某些功能经过复杂的JavaScript语义来实现并不合适,因此WebAssembly能够做为JavaScript的补集加入到Web阵营中来。WebAssembly最一开始的设计初衷就是做为不依赖于JavaScript的编译目标而存在,进而得到了主流浏览器厂商的普遍支持。很期待有一天WebAssembly可以发展起来,到那个时候,咱们用JavaScript编写的应用也会像如今用汇编语言写出的大型程序的感受咯~
前端用于数据展现
在笔者最先接触前端的时候,那个时候还不知道前端这个概念,只是知道HTML文件能够在浏览器中显示。彼时连GET/POST/AJAX这些概念都不甚明了,还记得那个时候看到一本厚厚的AJAX实战手册不明觉厉。笔者阅读过Roy Thomas Fielding博士的Architectural Styles andthe Design of Network-based Software Architectures这篇论文,也就是RESTful架构风格的源处。在这篇文章里,笔者反而感受最有感触的是从BS到CS架构的跃迁。一开始我以为网页是典型的BS的,咋说呢,就是网页是数据、模板与样式的混合,即以经典的APS.NET、PHP与JSP为例,是由服务端的模板提供一系列的标签完成从业务逻辑代码到页面的流动。因此,前端只是用来展现数据。
那个时候笔者更菜,对于CSS、JS都不甚明了,一切的数据渲染都是放在服务端完成的。笔者第一次学HTML的时候,惊呆了,卧槽,这能算上一门语言嘛?太简单了吧。。。原来作个网页这么简单啊,而后生活就华丽丽打了脸。那个时候,根本不会以script
或者link
的方式将资源载入,而是所有写在一个文件里,好吧,那时候连jQuery都不会用。记得那个时候Ajax都是本身手写的,长长的毫无美感的大量重复冗余的代码真是日了狗。
为何说HTML只是附庸之徒呢,那个时候咱们没有把Browser的地位与其余的Client并列,换言之,在经典的Spring MVC框架里,以下所示,用户全部的逻辑操做的核心咱们都会放置到Java代码中,根本不会想到用JavaScript进行控制。另外一个方面,由于没有AJAX的概念,致使了每次都是表单提交-后台判断-从新渲染这种方式。这样致使了每个渲染出来的网页都是无状态的,换言之,网页是依赖于后端逻辑反应不一样有不一样的呈现,自身没有一个完整的状态管理。
图片来源于《前端篇:前端演进史》
笔者最先的区分CS与BS架构,抽象来讲,会认为CS是客户端与服务器之间的双向通讯,而BS是客户端与服务端之间的单向通讯。换言之,网页端自己也变成了有状态。从初始打开这个网页到最终关闭,网页自己也有了一套本身的状态,而拥有这种变化的状态的基础就是AJAX,即从单向通讯变成了双向通讯。图示以下:
jQuery做为了影响一代前端开发者的框架,是Tools的典型表明,它留下了璀璨的痕迹与没法磨灭的脚印。笔者在这里以jQuery做为一个符号,来表明以Dom节点的操做为核心的一代的前端开发风格。那个年代里,要插入数据或者更改数据,都是直接操做Dom节点,或者手工的构造Dom节点。譬如从服务端得到一个用户列表以后,会经过构造<i>
节点的方式将数据插入到Dom树中。
可是不得不认可,在将来至关长的一段时间内,jQuery并不会直接退出历史的舞台,笔者我的认为一个重要的缘由就是如今仍然存在着很大比重的各式各样的基于jQuery的插件或者应用,对于崇尚拿来主义的咱们,不可避免的会继续使用着它。
jQuery引领了一个辉煌的时代,可是随着技术的演进它也慢慢在不少项目中隐去。jQuery这个框架自己很是的优秀而且在不断的完善中,可是它自己的定位,做为早期的跨浏览器的工具类屏蔽层在今天这个浏览器API逐步统一而且完善的今天,逐渐不是那么关键。所以,笔者认为jQuery会逐渐隐去的缘由可能为:
现代浏览器的发展与逐步统一的原生API
因为浏览器的历史缘由,曾经的前端开发为了兼容不一样浏览器怪癖,须要增长不少成本。jQuery 因为提供了很是易用的 API,屏蔽了浏览器差别,极大地提升了开发效率。这也致使不少前端只懂 jQuery。其实这几年浏览器更新很快,也借鉴了不少 jQuery 的 API,如 querySelector
,querySelectorAll
和 jQuery 选择器一样好用,并且性能更优。
前端由以DOM为中心到以数据/状态为中心
jQuery 表明着传统的以 DOM 为中心的开发模式,但如今复杂页面开发流行的是以 React 为表明的以数据/状态为中心的开发模式。应用复杂后,直接操做 DOM 意味着手动维护状态,当状态复杂后,变得不可控。React 以状态为中心,自动帮咱们渲染出 DOM,同时经过高效的 DOM Diff 算法,也能保证性能。
不支持同构渲染与跨平台渲染
React Native中不支持jQuery。同构就是先后端运行同一份代码,后端也能够渲染出页面,这对 SEO 要求高的场景很是合适。因为 React 等流行框架自然支持,已经具备可行性。当咱们在尝试把现有应用改为同构时,由于代码要运行在服务器端,但服务器端没有 DOM,因此引用 jQuery 就会报错。这也是要移除 jQuery 的迫切缘由。同时不但要移除 jQuery,在不少场合也要避免直接操做 DOM。
性能缺陷
jQuery的性能已经不止一次被诟病了,在移动端兴起的初期,就出现了Zepto这样的轻量级框架,Angular 1也内置了jqlite这样的小工具。前端开发通常不须要考虑性能问题,但你想在性能上追求极致的话,必定要知道 jQuery 性能不好。原生 API 选择器相比 jQuery 丰富不少,如 document.getElementsByClassName
性能是 $(classSelector)
的 50 多倍!
[
说这么多,只是想在之后技术选型的时候,能有一个通盘考虑,毕竟,这是曾经的Best Love。
若是当时的移动网络速度能够更快的话,我想不少SPA框架就不存在了。
随着踩得坑愈来愈多与相似于Backbone、AngularJs这样的更加纯粹全面的客户端框架的兴起,Single Page Application流行了起来。至此,在网页开发领域也就彻底变成了CS这种理念。至此以后,咱们会考虑在前端进行更多的用户交互与状态管理,而不是一股脑的所有交给后台完成。特别是页面的切换与不一样数据的呈现再也不是须要用户进行页面的跳转,从而在弱网状况下使用户得到更好的体验与更少的流量浪费。与此同时,前端就变得更加的复杂化,咱们也迫切的须要更加完善的代码分割与管理方案,因而,笔者开始尝试接触模块化的东西。笔者自RequireJs、SeaJs兴起以来一直关注,可是从未在实际项目中投入使用。额,第一次用这两个框架的时候,发现貌似须要对现有的代码或者喜欢的jQuery Plugins进行封装,当时我这种懒人就有点心理阴影了。不过SeaJs做为早期国人开发的有必定影响力的前端辅助工具,笔者仍是很是敬佩的。
在笔者知道模块化这个概念以前,文件夹是这么分的:
看上去很是的工整,可是稍微有个多人协做的项目,或者稍微多用一点jQuery的插件,看着那十来二十个不知道里面究竟是啥的JS文件,笔者是崩溃的。笔者最先打算使用模块化的动力来源于避免做用域污染,那个时候常常发现的问题是一不当心引进来的两个第三方文件就打架了,你还不知道怎么去修改。
模块通常指可以独立拆分且通用的代码单元,在ES6正式出来规范以前,咱们会选择使用RequireJs或者SeaJs来进行有点像依赖注入的东西:
require([ 'Tmpl!../tmpl/list.html','lib/qqapi','module/position','module/refresh','module/page','module/net' ], function(listTmpl, QQapi, Position, Refresh, Page, NET){
大概是这样子的,可是笔者就是以为好烦啊,而且它整个页面的逻辑仍是面向过程编码的。换言之,我若是页面上稍微换了个布局或者有那么三四个有交集的页面,那就日了狗了,根本谈不上复用。
Backbone是笔者较早期接触到的,以数据为驱动的一种框架。Backbone诞生于2010年,和响应式设计出如今同一个年代里,但他们彷佛在同一个时代里火了起来。若是CSS3早点流行开来,彷佛就没有Backbone啥事了。不过移动网络仍是限制了响应式的流行,只是在今天这些都有所变化。换言之,就是将数据的处理与页面的渲染分离了出来。算是在以jQuery那种以DOM操做为核心的基础上完成了一次变革。一样的笔者用过的框架还有easy-ui
,不过它是一个封装的更加彻底的框架。开发时,不须要考虑怎么去写大量的HTML/CSS代码,只须要在他的组件内填充不一样的逻辑与配置便可。很方便,也很不方便,记得笔者想稍稍修改下他的表格的功能都蛋疼了好一阵子。
Backbone相对而言会更开放一点,在笔者大量使用Angular的时候也有同窗提议使用Backbone + avaon这种更轻量级的方案。咱们用Ajax向后台请求API,而后Mustache Render出来,这里已经会开始将Web端视做一个完整的Client而不只仅是个附庸的存在。一个典型的Backbone组件的代码以下:
//《前端篇:前端演进史》 define([ 'zepto', 'underscore', 'mustache', 'js/ProductsView', 'json!/configure.json', 'text!/templates/blog_details.html', 'js/renderBlog' ],function($, _, Mustache, ProductsView, configure, blogDetailsTemplate, GetBlog){ var BlogDetailsView = Backbone.View.extend ({ el: $("#content"), initialize: function () { this.params = '#content'; }, getBlog: function(slug) { var getblog = new GetBlog(this.params, configure['blogPostUrl'] + slug, blogDetailsTemplate); getblog.renderBlog(); } }); return BlogDetailsView; });
能够看见,在Backbone中已经将DOM元素与数据渲染以及逻辑剥离了开来,这样就有助于进行团队内的分工与协做,以及大量的代码复用。那个时候常常会将Backbone与Angular进行对比,两者各有优劣。Backbone在显示模板、建立数据绑定和链接组件方面给使用者更多的选择。与之相反,Angular为这些问题提供了规定的方案,不过在建立模型与控制器方面的限制就比较少一些。笔者当时是由于想要用一套Framework来解决问题,因此仍是投入了Angular的怀抱。
AngularJs是第一个我真正喜欢的Framework,不只仅是由于它提出的MVVM的概念,还有由于它自带的DI以及模块化的组织方式。或许正是由于使用了AngularJs 1.0,笔者才没有深刻使用RequireJs、SeaJs这些吧。AngularJs 1.0的优秀与槽点就不细说了,在那个时代他成功让笔者有了一点完整的前端项目的概念,而不是多个分离的互相之间跳转的HTML文件。最近,AngularJs 2.0终于出了Beta版本,笔者也一直保持关注。不过我的感受唱衰的声音仍是会大于褒扬之声,从笔者我的感受而言,一个大而全的框架可能不如多个小而美的框架更加的灵活,关于这个对比能够参考下文的Web Components VS Reactive Components
这一章节。此外,对于AngularJs 中一直诟病的性能问题,Facebook提出的Virtual DOM的算法毫无疑问为前端的性能优化指明了一条新的道路,笔者这里推荐一个Performance Benchmarks,其中详细对比了多个DOM操做的库。笔者在这里只贴一张图,别的能够去原文查看:
整体而言,Vue偏轻量,适合移动端,ng适应pc端,avalon适合兼容老浏览器的项目。虽然Vue.js如今也有组件化的实现,包括相似于Flux的Vuex这样的Single State Tree的框架,可是笔者仍是比较倾向于把它当作一个MVVM模型来对待。
最初随着React的风靡,组件化的概念深刻人心。笔者一直坚信组件化是很是值得去作的事情,它在工程上会大大提高项目的可维护性及拓展性,同时会带来一些代码可复用的附加效果。但这里要强调的一点是,组件化的指导策略必定是分治而不是复用,分治的目的是为了使得组件之间解耦跟正交,从而提升可维护性及多人协同开发效率。若是以复用为指导原则那么组件最后必定会发展到一个配置繁杂代码臃肿的状态。组件化最著名的标准无疑是W3C制定的Web Components标准,它主要包含如下几个方面:
<template>模板能力
ShadowDom 封装组件独立的内部结构
自定义原生标签
imports解决组件间的依赖
不过这个标准自己还没发扬光大就被Angular、React这样的框架完爆了,不过他仍是指明了咱们组件化的几个准则:
资源高内聚:有点像Vue提到的理念,Single File Component。组件资源内部高内聚,组件资源由自身加载控制
做用域独立:内部结构密封,不与全局或其余组件产生影响
自定义标签:能够像使用HTML的预设标签同样方便地使用组件
可相互组合:组件正在强大的地方,组件间组装整合
接口规范化:组件接口有统一规范,或者是生命周期的管理
对于Web组件化的典型表明,应该是React与Angular 2。Angular 2基本上彻底革了Angular 1的命,Angular开发团队最先于2014年3月提出路线图,直到2015年末才进入alpha阶段。笔者自Angular 2开发之始就一直保持关注,见证了其规范或者接口的更迭。不能否认Angular 2在性能以及设计理念上都会比Angular 1先进不少,可是随着2014年中到2015年初以React为表明的组件式UI框架以及Flux/Redux为表明的响应式数据流驱动兴起,可能Angular 2并不会达到Angular 1的高度。笔者也在断断续续地更新一些Angular 2的指导与学习文档,不过确实,除了从零开始的大型项目,Angular 2仍是太笨重了。
Will Angular 2 be a success? You bet!(注意,评论更精彩)
实际上,在咱们选择一个库或者所谓的框架时,为咱们的组件选择一个合适的抽象可能会比以为哪一个框架更好更有意义。目前Web的组件化开发分为两个大的趋势,一个是以Angular 二、Polymer为表明的Web Components,另外一个是以React、Vue、Riot为表明的Reactive Components。目前Web Components方面由于各个库之间没法就如何定义它们达成一致,致使了相似于Angular 二、Aurelia这样的框架用它们本身的核心来定义Web Components。只有Polymer 100%实践了Web Components的规范。Web Components有点相似于Google,而React更像Facebook。
另外,当咱们选择一个框架时,还须要考虑清楚咱们是须要一个包含了全部的功能的执拗己见的框架,就像Angular二、Ember 2这样的,仍是一系列小的专精的框架的组合,就像React、Flux以及React Router这样的。固然,咱们在选择一个框架时还必须考虑进它潜在的变化的代价与难度,以及与其余的技术集成的难度,还有就是他有没有一个完善的生态系统。
就像笔者在本身的[AARF]()说起的,不管先后端,在这样同样敏捷式开发与快速迭代地背景下,咱们须要更多独立的分离的能够方便组合的相似于插件同样的模块。
随着WAP的出现与移动智能终端的飞速普及,开发者们不得不面临一个问题,大量的流量来自于手机端而再也不是PC端,传统的PC端布局的网页,在手机上显示的根本不友好,什么鬼!最先的时候人们考虑的是面向PC端与WAP设计不一样的页面,不过这样就毫无疑问将原来的工做量乘以二,而且产品管理与发布上也会存在着必定的问题,特别是在那个组件化与工程化理念尚未流行的时代里。因而,人们开始设计一套可以针对不一样的屏幕响应式地自反馈的布局方案,也就是这里提到的响应式设计。
响应式设计不得不提到的一个缺点是:他只是将本来在模板层作的事,放到了样式(CSS)层来完成。复杂度同力同样不会消失,也不会凭空产生,它老是从一个物体转移到另外一个物体或一种形式转为另外一种形式。
笔者最先接触到的响应式设计来自于BootStrap,它的Media Query功能给当时的笔者很大的惊喜的感受。特别是CSS3中Flexbox的提出,更是能方便地践行响应式设计的原则。不过,就以淘宝首页为例,若是用响应式方式完成一套代码在PC端与手机端不一样的彻底适应的展现效果,我以为还不如直接写两套呢。不能否认响应式设计在例如菜单啊,瀑布流布局啊这些功能组件上起到了很是巧妙的做用,可是为了单纯的追寻响应式布局而把整个CSS的逻辑判断搞得那么复杂,那我是拒绝的。特别是如今组件化这么流行的今天,我宁肯在根控件中自由的组织各个组件,也好过不断地自适应判断。
笔者不是很是提倡响应式解决方案来解决从PC端到移动端的迁移,笔者我的以为PC端和移动端就是额,不是同一种画风的东西。话说笔者接触过很多彻底用代码控制的响应式布局,譬如融云的Demo,它能够根据你显示器屏幕控制元素的显隐和事件。不能否认设计很精巧,可是在没有组件的那个时候,这种代码复杂度和性价比,在下服了。笔者在本身的实践中,对于纯移动端的响应式开发,譬如微信中的H5,仍是比较喜欢使用pageResponse这种方式或者它的一些改进版本。
响应式解决方案,表明着随着不一样的分辨率下智能的响应式布局。而移动优先的概念,笔者认为则是在界面设计之初即考虑到适应移动端的布局。固然,还有一个方面就是要照顾到移动端的浏览器的语法支持度、它的流量以及各类各样的Polyfill。
笔者很懒,最先的时候只是有一点Android开发经验,那个时候Hybrid技术刚刚兴起,每天看DZone上N多的炫耀本身的Hybrid开发多快、性能多好的文章,立马激发起了个人懒癌。写一波就能跨平台运行,多爽啊!Hybrid技术分为两个大的分支,一个以Cordova为表明的基于系统的WebView与本地调用。另外一种早期以Titanium、Tamarin,现在以React Native这样为表明的Cross Compilation,即跨平台编译技术。
在咱们须要学习C语言的时候,GCC就有了这样的跨平台编译。
在咱们开发桌面应用的时候,QT就有了这样的跨平台能力。
在咱们构建Web应用的时候,Java就有了这样的跨平台能力。
在咱们须要开发跨平台应用的时候,Cordova就有了这样的跨平台能力。
因而乎,在笔者第一次正式创业时,我斩钉截铁的跟投资人说,用Hybrid开发,用Cordova,没错的。记得那时候笔者还不懂iOS开发,因此在第一次正式作App的时候选择了Ionic 1.0。其实最先是打算用jQuery Mobile,不过写了第一个小的tab的Demo而后在本身的千元机上运行的时候,打开应用居然花了20多秒,当时投资人看到的时候脸是绿的,心是凉的。估计是那时候还不会用jQuery Mobile吧(虽然如今也不会),但确实不是一个可行方案。后来笔者转到了Ionic 1.0,确实一开始感受不错,速度还阔以。可是当时笔者还小,犯了一个很大的认知错误,就是打算彻底摒弃掉Native所有用Web技术开发,因而,一个简单地文件上传分分钟就教我作了人。最后产品作出来了,可是压根用不了。插一句,一开始为了在Android老版本设备上解决WebView的兼容性问题,打算用Crosswalk。笔者第一次用Crosswalk编译完成以后,吓尿了。速度上确实快了一点,可是包体上实在增长的太大了,臣妾作不到啊!至此以后,笔者熄灭了彻底依赖于Cordova进行APP开发的理念。
结果时间轴又错了,人们老是超前一个时期作错了一个在将来是正确的决定。大概是那个时候机器性能还不是足够的好吧。
Cordova或者Webview这种方向是没错的,如今也大量的存在于笔者的APP中,可是对于中大型APP而言,若是直接架构在Cordova之上,笔者仍是不推荐的。Build Once,Run Everywhere,貌似作不到了,或者说差强人意。那就考虑Learn Once,Write Everywhere。React Native又引领了一波时代潮流。
Cross Compilation的典型表明是NativeScript与React Native。笔者天然是更喜欢React Native的,毕竟背靠整个React生态圈,对于原生组件的支持度也是很好的。React框架自己虽好,可是仍是有许多能够与之媲美的优秀的框架的,可是React依靠Virtual DOM以及组件化等概念,依赖Facebook工程师强大的工程与架构能力,已经打造了一个完整的生态。特别是0.14版本以后的react与react-dom的分割,愈发的能够看出React的雄心壮志。将表现层与具体的界面分离开来,经过Canvas、Native、Server乃至将来的Desktop这样不一样的渲染引擎,保证了代码的高度重用性,特别是逻辑代码的重用性。
大部分时候咱们谈论到工程化这个概念的时候,每每指的是工具化。可是任何一个通向工程化的道路上都不可避免的会走过一段工具化的道路。笔者最先的接触Java的时候用的是Eclipse,那个时候不懂什么构建工具,不懂发布与部署,每次要用类库都要把jar包拷贝到Libs目录下。以致于多人协做的时候常常出现依赖相互冲突的问题。后来学会了用Maven、Gradle、Jenkins这些构建和CI工具,慢慢的才造成了一套完整的工做流程。前端工程化的道路,目标就是但愿能用工程化的方法规范构建和维护有效、实用和高质量的软件。
笔者我的感受的工程化的要素,会有如下几个方面:
统一的开发规范(语法/流程/工程结构)与编译工具。实际上考虑到浏览器的差别性,自己咱们在编写前端代码时,就等于在跨了N个“平台”。在早期没有编译工具的时候,咱们须要依赖本身去判断浏览器版本(固然也能够用jQuery这样人家封装好的),而后根据不一样的版本写大量的重复代码。最简单的例子,就是CSS的属性,须要加不一样的譬如-o-
、-moz-
这样的前缀。而这样开发时的判断无疑是浪费时间而且存在了大量的冗余代码。开发规范也是这样一个概念,JavaScript自己做为脚本语言,语法的严谨性一直比较欠缺,而各个公司都有本身的规范,就像当年要实现个类都有好几种写法,着实蛋疼。
模块化/组件化开发。在一个真正的工程中,咱们每每须要进行协做开发,以前每每是按照页面来划分,可是会形成大量的重复代码,而且维护起来会很是麻烦。这里的模块化/组件化开发的要素与上面的第一点都是属于开发需求。
统一的组件发布与仓库。笔者在使用Maven先后会有很大的一个对比感,没有一个统一的中央仓库与版本管理工具,简直就是一场灾难。这样也没法促进开发者之间的沟通与交流,会形成大量的重复造轮子的现象。
性能优化与项目部署。前端的错误追踪与调试在早期一直是个蛋疼的问题,笔者基本上每次都要大量的交互才能重现错误场景。另外一方面,前端会存在着大量的图片或者其余资源,这些的发布啊命名啊也是个很蛋疼的问题。当咱们在构建一个webapp的完整的流程时,咱们须要一套自动化的代码质量检测方案来提升系统的可靠性,须要一套自动化以及高度适应的项目发布/部署方案来提升系统的伸缩性和灵活性。最后,咱们须要减小冗余的接口、冗余的资源请求、提升缓存命中率,最终达到近乎极致的性能体验。
Webpack跟browserify本质上都是module bundler,差别点在于Webpack提供更强大的loader机制让其更变得更加灵活。固然,Webpack的流行天然仍是离不开背后的react 跟facebook。可是从如今HTTP/2标准的应用及实施进展来看,Webpack/browserify这种基于bundle的打包工具也面临着被历史车轮碾过的危机,相对的基于module loader的jspm反而更具前景。Browserify 可让你使用相似于 node 的 require() 的方式来组织浏览器端的 Javascript 代码,经过预编译让前端 Javascript 能够直接使用 Node NPM 安装的一些库。相较于Webpack,Browserify具备更悠久的历史,记得当年仍是看这篇文章才开始慢慢认识到Webpack,那时候Webpack仍是一个至关年轻的框架啊。
Webpack是前端开发真正意义上成为了工程级别,而再也不是随意,能够看看这篇文章。笔者第一次看Webpack的时候,没看懂。当时用Gulp用的正顺手,不须要本身往HTML文件里引入大量的Script文件,还能自动帮你给CSS加先后缀,自动地帮你压缩,多好啊。不过Grunt和Gulp如今存在的问题就是须要本身去组装大量的插件,良莠不齐的插件质量致使了大量时间的浪费。而且Gulp/Grunt还并不能称为一个完整的编译工具,只是一个辅助工具。
Webpack还有很令笔者欣慰的一点,它支持Lazy Load Component,而且这种懒加载技术是与框架无关的。这样就避免了笔者在编码时还须要考虑固定的组件或者代码分割,毕竟在一个快速迭代的项目中仍是很难在一开始就规划好所有的组件分割。这一点对于笔者这种被SPA JS加载以及原来的不管是基于Angular的懒加载仍是React Router的懒加载折磨的人是一个大大的福音。同时,Webpack还支持配合了React Hot Loader的代码热插拔,能够大大地提升代码的开发效率。毕竟等着Browserify编译好也是很蛋疼的。
在笔者的我的的感触中,Webpack是促成了前端真正工程化的不可缺乏的一环。记得以前看过美团的前端技术分享,它提出了前端分布式编译系统。大型系统的分布式编译很常见,可是在前端,这典型的脚本与解释执行的领域,出现了大型分布式编译系统,仍是很让人震惊的。笔者是个懒惰的人,懒人总但愿能够用一套方法去解决所有的问题,因此慢慢的笔者彻底切入到了Webpack。或许将来某天也会离开Webpack,就像离开jQuery同样,可是会永远记得陪我走过的这些岁月。
现代这样一个云计算与大数据的时代,Data Driven的概念早已深刻人心。随着WEB应用变得愈来愈复杂,再加上node先后端分离愈来愈流行,那么对数据流动的控制就显得愈加重要。笔者在开篇就说起过,前端变革的一个核心路线就是从以DOM Manipulation为核心到以State为核心,这样也就能将逻辑控制、渲染与交互给分离开来。用一个函数来表示,如今的渲染就是:$UI=f(state)$。在React中$f$能够看作是那个render函数,能够将state渲染成Virtual DOM,Virtual DOM再被React渲染成真正的DOM。在控制器中,咱们不须要关心DOM是如何变动的,只须要在咱们的业务逻辑中完成状态转变,React会自动将这个变动显示在UI中。其实在Angular中也是这样,只不过Angular中采起的数据双向绑定与脏检测的技术,而React中采用的是JSX这样来完成一种从状态到页面的绑定。
这样一种以响应式数据流驱动的页面,毫无疑问会将编程工做,特别是复杂的交互与逻辑处理变得更加明晰,也方面了产品迭代与变动,也就是敏捷式开发的理念。采用这样的响应式数据流驱动的方式,还有一个很大的好处就是方便错误追踪与调试。SPA State is hard to reproduce!
而在Redux这样的框架中,存在着相似于Global State Object这样的能够将页面所有还原,来重现Bug的东西。当测试人员/用户遇到问题的时候,主动将当时的State发送给开发人员,开发人员就阔以直接根据State来还原现场咯。Immutable的魅力正在于此,灵活的可追踪性。
Redux是在flux的基础上产生的,在此基础上它引入了函数式编程、单一数据源、不可变数据、中间件等概念,基本思想是保证数据的单向流动,同时便于控制、使用、测试。Redux不依赖于任意框架(库),只要subscribe相应框架(库)的内部方法,就可使用该应用框架保证数据流动的一致性。Redux在必定程度上能够说是今年React生态甚至整个前端生态中影响最大的一个框架,它给整个前端技术栈引入了不少新成员,尽管这些概念可能在其余领域已经有了普遍的应用。笔者仍是比较推崇响应式开发的,实际工做中用的比较多的仍是FPR的一些实现,譬如RxJava啊这些。Redux标榜的是Immutable的State Tree,而Vue采用的是Mutable的State Tree。
笔者在不长的代码之路上从Windows Developer 到 Pentester,到 Android Developer,到 Server-Side Developer,最后选择了Front-end 做为本身的归宿。不过Server-Side Architecture 和 Data Science也是个人最爱,哈哈哈哈哈哈,怎么有一种坐拥后宫的赶脚~
但愿能永远在这条路上,心怀激情,热泪盈眶。