被查封的wwW311ee地还有在恢复正常com的可能吗

&figure&&img src=&https://pic1.zhimg.com/v2-63b61c3c2e5fefb5e5a7774270bdc2b7_b.jpg& data-rawwidth=&1620& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1620& data-original=&https://pic1.zhimg.com/v2-63b61c3c2e5fefb5e5a7774270bdc2b7_r.jpg&&&/figure&漫长的几年当中社区里讨论 JavaScript 和函数式编程的声音很多, 我无法的详细的去追踪, 也不是本文重点. 鼓吹 JavaScript 函数式编程的大的声音, 我的印象里主要是两次.&p&第一轮是经常能看到社区当中引用的 Douglas Crockford 在 2001 年写的文章. 后来常用的 Underscore 也继承了类似的思路来发挥函数式编程的一些好处. JavaScript 设计之初借鉴了 Scheme 的一些策略, 将函数作为一等公民, 支持被灵活传递使用. 以及有词法作用域以及闭包这些函数式编程的基础性结构. 这些赋予了 JavaScript 极大的灵活度通过函数来模拟各种需求.&/p&&br&&p&&a href=&https://link.zhihu.com/?target=http%3A//www.crockford.com/javascript/javascript.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The World's Most Misunderstood Programming Language&/a&&br&&/p&&blockquote&JavaScript's C-like syntax, including curly braces and the clunky for statement, makes it appear to be an ordinary procedural language. This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java. It has arrays instead of lists and objects instead of property lists. Functions are first class. It has closures. You get lambdas without having to balance all those parens.&/blockquote&&p&第二轮是 React 触发到大量对于函数式编程的思考, 同期发生的还有 Elm 的 FRP 方案在社区引起巨大反响, 以及 Om 社区反馈到 React 社区一些技术和概念. 当中重要的概念有纯函数和不可变数据. 在 React 的渲染模型当中的, Store updates 和 Component rendering 两个过程需要隔离副作用以保证自由地复用, 而不可变数据则通过结构共享提供了性能优化的方案. 相关的讨论很多, 比如 &a href=&https://link.zhihu.com/?target=https%3A//medium.com/%40chetcorcos/functional-programming-for-javascript-people-%23.649i69moy& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Functional Programming for JavaScript People&/a&.&/p&&br&&p&这些观点, 给人的感觉是 JavaScript 很适合函数式编程, 比如自带的数组操作方法常常能串联出比较漂亮的写法, 而且 React 在社区就算不能通吃, 但是已经取得了如此广泛的影响, 让大量的开发者接受了 reducer 纯函数这样的观念, 并在组件抽象上用于很多函数式编程的手法, 逐渐构建了强大的技术栈. 最终, 通过这些来验证 JavaScript 在函数式编程使用上的成功, 某种程度上算是自圆其说了, 而且也做出了成绩.&/p&&p&但是这种理解从不同的角度观察, 还是存在问题的. 我从比较早就接触到了 CoffeeScript 以及深刻影响到它的语言: Haskell. 到现在, 我有三年多 CoffeeScript 开发的经验, 一年的 ClojureScript 小项目的经验, 以及勉强入门的 Haskell 学习经验. 站在 JavaScript 之外, 看到的情况跟在 JavaScript 社区内部看到的并不一样.&/p&&p&首先 Wiki 上的定义, 可以看两点, 1) 用数学函数类似的表达式来定义计算过程, 而不是用汇编那样指令来描述计算, 2) 函数结果严格依赖于它的输入, 其他的影响结果的因素比如可变状态, 是要消除掉的(追加: 感兴趣看下这个视频 &a href=&https://link.zhihu.com/?target=https%3A//www.youtube.com/watch%3Fv%3DLnX3B9oaKzw& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Functional Programming & Haskell - Computerphile&/a&):&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Functional_programming& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Functional programming&/a&&br&&/p&&blockquote&In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions[1] or declarations[2] instead of statements. In functional code, the output value of a function depends only on the arguments that are input to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) each time. Eliminating side effects, i.e. changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming.&br&&/blockquote&&p&如果详细看 Wiki 会发现信息量非常大, 涉及到的编程语言有几十种, 而且还有&纯函数语言&的分类把某些语言划分出来, 而 JavaScript 被划分到了非函数式编程语言的一类里边叫做 &Functional programming in non-functional languages&. 我接触过的函数式语言, 大致分类是 ML 系(Standard ML, OCaml, Haskell), Scheme 系(Racket, Guile, Chicken), CommonLisp 系(CommonLisp, EmacsLisp), Erlang 系(Erlang, Elixir), 还有特立独行的 Scala, Shen 之类的. 当你去了解函数式编程的时候, JavaScript 其实根本没有位置.&/p&&p&函数式编程的深度广度挺复杂, 特别是在后端, 知名的例子比如 Facebook 用 Haskell 解决垃圾邮件过滤的性能问题, 或者 Clojure 作者的数据库 Datomic 的整体设计. 我作为前端开发者, 很难说出具体的细节来. 但显然不是前端用级联写法组合函数以及写写高阶函数那么简单.&/p&&br&&p&所以换个角度来看待一些方面:&/p&&ul&&li&JavaScript 能做函数式编程吗? 能.&br&&/li&&li&JavaScript 满足函数式编程所有的约束吗, 或者说大部分? 基本没法约束 JavaScript.&/li&&li&JavaScript 函数式编程用得巧妙吗, 有效吗? 看情况, 不一定.&/li&&/ul&&p&这篇文章是为了明确说明 JavaScript 在函数式编程方面支持太少. 我不能从具体 Haskell 代码去解释, 那么换个办法, 按照概念来对比来看 JavaScript 做了什么. 下面的概念我参照一篇文章上的, 以 Clojure 还有 Haskell 为参照. 由于 Haskell 是函数式编程圈子里教科书式的语言, 基本上概念就是遵照 Haskell 罗列的: &a href=&https://link.zhihu.com/?target=https%3A//medium.com/%40jlouis666/on-functional-programming-df28cc9078de%23.x6dqbyu22& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&On Functional Programming&/a&&br&&/p&&ul&&li&Functions as first-class values, 函数一等公民, 可以把函数作为参数传递, 从而构造出高阶函数各种用法. 这个用法各种语言都支持了: Lua 支持, Python 似乎也支持, Java 也开始支持了, 我会的语言少都举不出来不支持传函数的流行语言.&/li&&li&Pure functions, 纯函数. 可以写, 但也有很大区别. JavaScript 没限制, 从而不能预判函数纯或者不纯. Clojure 遵循 Lisp 风格的约定, 带副作用的函数一般用 `f!` 这种叹号结尾的写法命名, 而编译器没有约束. Haskell 是严格约束的, 出了名的 IO Monad 就是因为遵循纯函数导致副作用难以直接用数学函数表达出来, 最终精心设计出一个概念.&/li&&li&Referential transparency, 引用透明, 所以表达式可以被其运算结果完全替换掉, 也就是要求控制甚至避免副作用. &br&&/li&&li&Controlled effects, 受控的副作用, 主要手段是隔离. JavaScript 需要人为地去隔离, 语言层面完全没有限制. Clojure 也需要人为隔离, 就像前面说的 `f!` 那样的约定, 同时规定了数据不可变, 再加上作者有意在语言中强调控制副作用, 实际上副作用少得多. Haskell 通过类型系统限定, 不隔离副作用无法通过编译的.&br&&/li&&li&Everything is an expression, 一切皆是表达式. JavaScript 做不到, 导致设计 DSL 时候很头疼, 倒是 CoffeeScript 做到了. Clojure 继承了 Lisp, 很明显一切皆是表达式. Haskell 代码里都是函数, 除了类型声明和语法糖部分, 也是一切皆是表达式.&br&&/li&&li&No loops, 换句话说, 不能用 for/while, 因为这两个写法当中的 `i++` 依赖可变数据. JavaScript 经常使用 for/while. Clojure 当中的循环基本上用尾递归实现, 同时也提供了 doseq 之类的 Macro 让循环过程很好写. Haskell 就是完全尾递归的写法了.&br&&/li&&li&Immutable values. JavaScript 默认可变, 仅有的手段用 `Object.freeze` 可以强行锁定对象或者 const 锁定变量本身, 另外就是 immutable-js 那样的共享结构的不可变数据作为类库来实现. Clojure 是把不可变数据和结构共享作为语言的基础, 专门设计了 Atom 类型用于模拟共享的可变状态, 也不排除某些场景和宿主语言的互操作还是会有可变数据. Haskell 默认就是不可变数据, 也有 IORef 相关的代码可以模拟可变状态, 但在教程里几乎看不到.&br&&/li&&li&Algebraic Datatypes, 代数类型系统. JavaScript 没有静态类型系统, TypeScript 有类型, 但和代数类型还不一样. Clojure 没有静态类型系统, 就算有而只是很基础的类型检查, 或者用 Specs 做详细运行时检查. Haskell 有强大的代数类型系统, 即便是副作用也被涵盖在类型系统当中.&br&&/li&&li&Product types. Haskell 通过代数类型系统支持.&br&&/li&&li&No Null. JavaScript 当中有 undefined 和 null. Clojure 当中只有 nil. Haskell 里没有 null 也没有 nil, 而是用了 Maybe Monad 这样的概念, 通过类型系统进行了抽象和限制. null 的问题很深, 网上找解释吧, 我还没理解清楚, 只了解到满足了方便却造成了意料之外的复杂度.&/li&&li&A function always returns a value, 函数永远都有返回值, 类似一切皆是表达式那个问题. 比如 Haskell 里会有的叫做 Unit 的 `()` 空的值. 这个有点费解...&br&&/li&&li&Currying, 柯理化. JavaScript 和 Clojure 也能模拟, 而在 Haskell 当中是默认行为.&br&&/li&&li&Lexical scoping, 词法作用域. 三者都支持.&br&&/li&&li&Closures, 闭包, 都支持.&br&&/li&&li&Pattern matching, 模式匹配. 类似解构赋值之类的在 JavaScript 和 Clojure 当中通过语法糖也算有这个功能, 但是跟 Haskell 以及 Elixir 当中的用法对比起来差距很大. 比如说 Haskell 甚至能定义 `let 1 + 1 = 3` 来覆盖 `+` 的行为, 虽然是奇葩的现象, 但这就是一个定义的 pattern, 在 JavaScript 和 Clojure 都没有这种情况.&br&&/li&&li&Lazy evaluation, 惰性计算. JavaScript 是严格求值的, 不支持惰性计算. Clojure 支持 Lazy, 然而由于 Clojure 又允许了一些副作用, 实际上某些特殊场景会需要手动 force 代码执行, 也就是说不完美. Haskell 采用惰性计算. 惰性计算就是说代码里的表达式被真正使用来才会真正执行, 否则就像是个 thunk, 继续以表达式存储着. 我印象里 Elm 社区说过, 对于图形界面来说 Lazy 反而是多余的.&/li&&/ul&&p&大致做个总结, 就是 Haskell 当中的类型系统, 不可变数据, 控制副作用, 在 Clojure 当中只是做了不可变数据, 同时稍微控制了一下副作用, 而这些概念在 JavaScript 当中很少有支持. 这样的结果, JavaScript 写出来的代码几乎都是不符合函数式编程的限制得.&/p&&p&不可变数据对程序的直接影响就是 for/while 没法写了. 可以想象一下, 如果你代码当中不让写可变数据, 这会是多大的影响, 会极大地影响了代码编写和开发的习惯的. 因为我们通常需要可变的状态来完成通信, 而且还要以 for/while 作为结构来构造程序, 抛开可变状态大学里学的内容很多都用不了了. 思维方式的转变, 是个不小的挑战.&/p&&p&同时也要注意, 函数式编程用的说法是&隔离副作用&, 而不是说&去掉&副作用. 比如在 Clojure 当中, 要用共享可变状态的场景, 就要明确声明数据类型是 Atom, 更新数据用到的函数也不一样, 结果是实际使用当中会很有意识地去思考哪些地方直接用尾递归就写完了, 哪些迫不得已要使用 Atom 类型, 这种把可变状态明确区分来的意识在 Clojure 当中经常有. 还有就是比如 IO 这样的副作用, Clojure 当中虽然限制, 但是很松散, 即便写了编译器也不会说什么. Haskell 类型系统强制要求隔离好副作用, 不过我觉得对于大部分开发者来说这样既复杂又多此一举.&/p&&p&与之形成鲜明对比, JavaScript 设计时完全不在乎这些约定, 即便是模仿了 Scheme, 当年 PLT Scheme 那样的语言, 本身也没有限制好数据 immutable(目前 Racket 数据支持 mutable 和 immutable 两种形态, 也是神奇), 也只用了 `f!` 写法来标明副作用, 到了 JavaScript 连副作用都不标记. 结果说来说去, JavaScript 真正和函数式编程搭上的, 也就是闭包和函数一等公民嘛.&/p&&p&而且原本在函数式编程当中, 返回结果只是和参数改变有关, 每个数值又是引用透明的, 即便要做大量的抽象也能放心去做, 不担心出错. 到了 JavaScript 当中, 由于函数可以混用可变数据, 另外加上 this 指针的用法, 经过高阶函数抽象之后, 整个代码可能会变得难以预测, 这样函数式编程的可靠性就无法得到保障了. JavaScript 确实算是学到了函数式编程的技巧具备了灵活性, 但是却很难达到 Clojure 那样的可靠性, 甚至某些情况说不准因为函数抽象而引发更加麻烦的局面.&/p&&br&&p&所以, 我的结论就是, JavaScript 学了几招厉害的, 确实能干点厉害的事情, 但是, 距离把功夫练好还差太远.&/p&&br&&p&这篇文章我主要是吐槽 JavaScript 宣传函数式编程在误导人. 我很多时间在跟进着 Clojure 社区, 对于 Haskell 我只能在边上围观, 我能看到的就是函数式编程水真的很深, 我的文章当中很可能有不准确的地方, 看到的话请评论指出.&/p&&br&&p&作者简介: 题叶,饿了么前端工程师,主攻单页面应用和函数式编程。参与过简聊的开发,简聊是国内比较早开始深度尝试 React.js Webpack 构建复杂单页面应用的团队。活跃在 React 社区,Clojure 社区,是 React 中文论坛和中文社区主要发起人之一。&/p&
漫长的几年当中社区里讨论 JavaScript 和函数式编程的声音很多, 我无法的详细的去追踪, 也不是本文重点. 鼓吹 JavaScript 函数式编程的大的声音, 我的印象里主要是两次.第一轮是经常能看到社区当中引用的 Douglas Crockford 在 2001 年写的文章. 后来常用的…
&figure&&img src=&https://pic4.zhimg.com/v2-418fcf68fe_b.jpg& data-rawwidth=&1426& data-rawheight=&749& class=&origin_image zh-lightbox-thumb& width=&1426& data-original=&https://pic4.zhimg.com/v2-418fcf68fe_r.jpg&&&/figure&&blockquote&&p&官网:&a href=&https://link.zhihu.com/?target=http%3A//stateofjs.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&the state of JavaScript 2016&/a&&/p&&p&发起人:&a href=&https://link.zhihu.com/?target=http%3A//twitter.com/SachaGreif& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sacha Greif&/a&&/p&&p&整理翻译:&a href=&https://www.zhihu.com/people/yubolun& class=&internal&&余博伦&/a&&/p&&p&我已委托 &b&&a href=&https://link.zhihu.com/?target=http%3A//rightknights.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&维权骑士&/a&&/b&为我的文章进行维权行动。&/p&&p&如需转载请访问 &a href=&https://link.zhihu.com/?target=http%3A//rightknights.com/pub/pub_author%3FgreatAuthor%3DBFBED& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&rightknights.com/pub/pu&/span&&span class=&invisible&&b_author?greatAuthor=BFBED&/span&&span class=&ellipsis&&&/span&&/a& 获得合法授权。&/p&&/blockquote&&p&有人认为JavaScript是最好的语言,有人认为它一团糟。可按照C++之父的话来讲:&/p&&blockquote&&p&世界上只有两种编程语言:一种是天天被人喷的,另一种是没人用的。&/p&&/blockquote&&p&不论你喜欢承认与否,JavaScript已经一天比一天火了,甚至火得有点过头,生态圈太过繁荣,每个月都可能有新的相关构建工具、开发框架或者别的什么库发布。如果你想了解更多,请查阅:&/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&你的第一门编程语言应该学什么??d???s???? :???su?&/a&&/p&&p&前段时间歪果仁对JS的发展现状专门做了一个调查,发起者是&a href=&https://link.zhihu.com/?target=http%3A//twitter.com/SachaGreif& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sacha Greif&/a&(之前本专栏也发过他的一篇文章&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.)&/a&)。全世界有超过9000名开发者参与了此次调查,内容涉及:&/p&&ol&&li&代码风格(JS预编译语言)&/li&&li&前端框架&/li&&li&状态管理&/li&&li&API层&/li&&li&全栈框架&/li&&li&测试框架&/li&&li&CSS 构建工具/预处理器&/li&&li&构建工具&/li&&li&移动端框架&/li&&li&新特性&/li&&/ol&&p&以及一些别的JS相关话题的意见和讨论。&/p&&h2&JavaScript的发展现状&/h2&&blockquote&&p&JavaScript已经逐步发展成为了一门流行可靠的语言,但与此同时也变得臃肿起来,框架工具之间各种复杂的依赖甚至能让你崩溃。&/p&&p&对于本来就有选择恐惧症的你来说更是噩梦:你应该用React还是Angular 2?你真的需要使用Webpack么?这个月又有什么新的处理CSS的解决方案?&/p&&p&我每天也会为类似的问题头疼,所以才有了这个调查,我在2周的时间里就收到了超过9000份回复。&/p&&/blockquote&&h2&代码风格&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&ES6成为了新的标准&/li&&li&CoffeeScript已经过气了&/li&&li&新一波的流行趋势正在袭来&/li&&/ul&&p&JavaScript拥有不止一种语法,自2009年CoffeeScript出现后,各式各样的JS语法,转编译语言如雨后春笋般涌现出来:ES6, TypeScript, Elm……&/p&&figure&&img src=&https://pic3.zhimg.com/v2-022b30409fad0fdf435cf5_b.jpg& data-rawwidth=&931& data-rawheight=&838& class=&origin_image zh-lightbox-thumb& width=&931& data-original=&https://pic3.zhimg.com/v2-022b30409fad0fdf435cf5_r.jpg&&&/figure&&p&先解释一下这个统计图怎么看,受访者一共有5种选项:&/p&&ol&&li&Never heard of it 从来没听说过&/li&&li&Heard of it, not interested 听说过但是没兴趣&/li&&li&Heard of it, would like to learn 听说过,打算学着用用看&/li&&li&Used it before, would not use again 用过了,不想再用了&/li&&li&Used it before, would use again 用过,并且还会继续用下去&/li&&/ol&&p&ES6, &a href=&https://link.zhihu.com/?target=http%3A//coffeescript.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CoffeeScript&/a&, 和 &a href=&https://link.zhihu.com/?target=https%3A//github.com/Microsoft/TypeScript& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TypeScript&/a&都已经家喻户晓了,而TypeScript看上去却并没有另外两个那么受欢迎。&/p&&p&&a href=&https://link.zhihu.com/?target=http%3A//elm-lang.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Elm&/a& 和 &a href=&https://link.zhihu.com/?target=https%3A//clojurescript.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ClojureScript&/a&就不是那么广为人知了,它们还多少局限在自己独立的生态体系里。&/p&&p&虽然ES6还没有正式被浏览器兼容,可是绝大多数开发者都已经尝试过它的语法了。&/p&&p&TypeScript 和 Elm可能是因为对普通的JS开发者来说不是特别友好,所以很多人都是抱着想试试的态度却还没有尝试过,毕竟对于只知道JS的程序员来说,静态类型都是很难理解的概念。&/p&&h2&前端框架&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&选择React准儿没错&/li&&li&Vue越来越火&/li&&li&Angular 2 要比 1 强&/li&&/ul&&figure&&img src=&https://pic2.zhimg.com/v2-8bb941b163add6c314e4e1e_b.jpg& data-rawwidth=&925& data-rawheight=&838& class=&origin_image zh-lightbox-thumb& width=&925& data-original=&https://pic2.zhimg.com/v2-8bb941b163add6c314e4e1e_r.jpg&&&/figure&&p&框架的优劣经常是人们争论的焦点。在调查提供的几个选项中,除了比较新的Vue以外,所有框架基本都是人尽皆知的。&/p&&p&Angular 2 才刚刚推出,所以它从开发阶段到实际应用肯定还有个过程。从统计数据上来看,React是毫无争议的赢家。由于Vue卓越的性能表现,它在满意度方面已经排到了第二位。&/p&&p&补录其他:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-a170e58e5d872bb7f62efccddf336606_b.jpg& data-rawwidth=&925& data-rawheight=&840& class=&origin_image zh-lightbox-thumb& width=&925& data-original=&https://pic4.zhimg.com/v2-a170e58e5d872bb7f62efccddf336606_r.jpg&&&/figure&&h2&状态管理&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&Redux 是最火的&/li&&li&大家采用的其实还是Flux的理念&/li&&/ul&&figure&&img src=&https://pic1.zhimg.com/v2-bfeea814b06d7fcedc689d60e9df0f24_b.jpg& data-rawwidth=&926& data-rawheight=&838& class=&origin_image zh-lightbox-thumb& width=&926& data-original=&https://pic1.zhimg.com/v2-bfeea814b06d7fcedc689d60e9df0f24_r.jpg&&&/figure&&p&状态管理逐渐成为了一种新类型的JS轮子。当前并不是对所有的开发者都适用。&/p&&p&Redux显然是最火了,而作为Redux第一大替代品的Mobx,仍然有很多人没听说过。&/p&&p&Redux的开发者Dan Abramov自己也反复强调过,并不是所有的应用都需要使用Redux,等到你真正有相关需求的时候再说。&/p&&p&补录其他:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-fbf325d241aeb86de390c_b.jpg& data-rawwidth=&875& data-rawheight=&942& class=&origin_image zh-lightbox-thumb& width=&875& data-original=&https://pic1.zhimg.com/v2-fbf325d241aeb86de390c_r.jpg&&&/figure&&h2&API 层&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&GraphQL 看起来比较有前途&/li&&li&REST APIs 仍然是最广泛适用的&/li&&/ul&&figure&&img src=&https://pic4.zhimg.com/v2-454bd0dcdf3a72f4970a37_b.jpg& data-rawwidth=&935& data-rawheight=&833& class=&origin_image zh-lightbox-thumb& width=&935& data-original=&https://pic4.zhimg.com/v2-454bd0dcdf3a72f4970a37_r.jpg&&&/figure&&p&REST APIs肯定就不用说了,大家都在用。&a href=&https://link.zhihu.com/?target=https%3A//firebase.google.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Firebase&/a&因为它自身实时BaaS(back-end-as-a-service)的特性也算拥有了一定的占有率(国内的朋友假如你没听说过Firebase,那你多少应该听说过某狗实时后端云)。&/p&&p&而近一段时间被炒得火热的&a href=&https://link.zhihu.com/?target=http%3A//graphql.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GraphQL&/a&,虽然有很多人感兴趣,肯定还需要一定时间才能发展起来。&/p&&p&补录其他:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-afd06a1dda_b.jpg& data-rawwidth=&941& data-rawheight=&1622& class=&origin_image zh-lightbox-thumb& width=&941& data-original=&https://pic3.zhimg.com/v2-afd06a1dda_r.jpg&&&/figure&&h2&全栈框架&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&最主流的是Meteor和MEAN&/li&&li&这种“一体化”框架并没有那么受欢迎&/li&&/ul&&figure&&img src=&https://pic2.zhimg.com/v2-bc95ed2b1a2e_b.jpg& data-rawwidth=&926& data-rawheight=&828& class=&origin_image zh-lightbox-thumb& width=&926& data-original=&https://pic2.zhimg.com/v2-bc95ed2b1a2e_r.jpg&&&/figure&&p&&a href=&https://link.zhihu.com/?target=http%3A//meteor.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Meteor&/a& 是全栈框架里的领导者。与此同时,使用&a href=&https://link.zhihu.com/?target=http%3A//mean.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&MEAN&/a&(Mongo + Express + AngularJS + Node.js)架构的开发者也有很多,并且在满意度方面它是表现最好的。&/p&&p&除此之外,火起来的还有用React-Redux替代AngularJS的&a href=&https://link.zhihu.com/?target=http%3A//mern.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&MERN&/a&框架。&/p&&h2&测试框架&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&最主流的是Mocha和Jasmine&/li&&li&开发者总体上对JS的测试不是特别满意&/li&&/ul&&figure&&img src=&https://pic1.zhimg.com/v2-9a496f0cd027aea32fb745afbebf8c03_b.jpg& data-rawwidth=&926& data-rawheight=&835& class=&origin_image zh-lightbox-thumb& width=&926& data-original=&https://pic1.zhimg.com/v2-9a496f0cd027aea32fb745afbebf8c03_r.jpg&&&/figure&&h2&CSS 构建工具/预处理器&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&SASS/SCSS是主导&/li&&li&CSS Modules 值得一试&/li&&/ul&&figure&&img src=&https://pic2.zhimg.com/v2-b4be6daafbd47b7dbdfad503ce66e69d_b.jpg& data-rawwidth=&932& data-rawheight=&846& class=&origin_image zh-lightbox-thumb& width=&932& data-original=&https://pic2.zhimg.com/v2-b4be6daafbd47b7dbdfad503ce66e69d_r.jpg&&&/figure&&p&CSS看上去可能和JavaScript没什么关系,可越来越多的构建工具和框架中把它们结合到了一起。&/p&&p&CSS本身也像JS一样,有着很多受人诟病的缺点。所以人们发明了很多CSS预处理器或者工具等等,来扩展优化原生的CSS,例如&a href=&https://link.zhihu.com/?target=http%3A//sass-lang.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SASS&/a&, &a href=&https://link.zhihu.com/?target=http%3A//lesscss.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LESS&/a&, 和 &a href=&https://link.zhihu.com/?target=https%3A//github.com/css-modules/css-modules& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CSS Modules&/a& .&/p&&p&关于CSS Modules本专栏之前专门发布过一个系列入门教程:&/p&&ul&&li&第一部分:&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&什么是CSS Modules?为什么要使用它?&/a&&/li&&li&第二部分:&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&如何上手CSS Modules&/a&&/li&&li&第三部分:&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&在React中使用CSS Modules&/a&&/li&&/ul&&p&补录其他:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-6af957d173bc76fb73f6_b.jpg& data-rawwidth=&913& data-rawheight=&583& class=&origin_image zh-lightbox-thumb& width=&913& data-original=&https://pic1.zhimg.com/v2-6af957d173bc76fb73f6_r.jpg&&&/figure&&h2&构建工具&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&Webpack 和 Gulp最受欢迎&/li&&li&Grunt 已经过气了&/li&&/ul&&figure&&img src=&https://pic1.zhimg.com/v2-a35d54325e_b.jpg& data-rawwidth=&920& data-rawheight=&831& class=&origin_image zh-lightbox-thumb& width=&920& data-original=&https://pic1.zhimg.com/v2-a35d54325e_r.jpg&&&/figure&&p&调查中涉及的每种工具还都算比较主流的。不出意外,只有两岁的&a href=&https://link.zhihu.com/?target=https%3A//webpack.github.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Webpack&/a&是最大的赢家(知名度/吸引力/满意度综合),Webpack是一种可以打包构建一切甚至包括你的图片音视频一类静态资源的工具,而且可以灵活配套各种插件使用。&/p&&p&补录其他:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-5f0f402bd0ecee2a730c2d_b.jpg& data-rawwidth=&930& data-rawheight=&753& class=&origin_image zh-lightbox-thumb& width=&930& data-original=&https://pic1.zhimg.com/v2-5f0f402bd0ecee2a730c2d_r.jpg&&&/figure&&h2&移动端框架&/h2&&p&&strong&总评:&/strong&&/p&&ul&&li&原生应用还是最主流的解决方案&/li&&li&React Native 证明了它自己&/li&&/ul&&figure&&img src=&https://pic3.zhimg.com/v2-b6ae9aef1ced4d7d22819c_b.jpg& data-rawwidth=&931& data-rawheight=&833& class=&origin_image zh-lightbox-thumb& width=&931& data-original=&https://pic3.zhimg.com/v2-b6ae9aef1ced4d7d22819c_r.jpg&&&/figure&&p&通过JS来开发移动应用的这种实现才出现不久,大部分人还是在采用开发原生App的解决方案。&/p&&p&但原生的弊病是你必须专门为相应的系统平台开发,这样下来就会有很高的成本。&/p&&p&JavaScript提供了一种同时开发iOS/Android平台应用的解决方案(WP用户哭晕在厕所)。只掌握前端开发语言的程序员甚至可以在各种设备上写App了,越来越多的人开始使用这类技术。&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//facebook.github.io/react-native/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&React Native&/a&在满意度和受欢迎程度上都是表现最好的。&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//cordova.apache.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Cordova&/a& 和 &a href=&https://link.zhihu.com/?target=http%3A//phonegap.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PhoneGap&/a& 越来越不行主要是因为它们的性能实在是个问题。&/p&&p&补录其他:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-edd7fd825db72b_b.jpg& data-rawwidth=&779& data-rawheight=&525& class=&origin_image zh-lightbox-thumb& width=&779& data-original=&https://pic3.zhimg.com/v2-edd7fd825db72b_r.jpg&&&/figure&&h2&&a href=&https://link.zhihu.com/?target=http%3A//stateofjs.yubolun.com/2016/features/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&新特性&/a&&/h2&&p&&strong&服务器端渲染&/strong&&/p&&p&JavaScript 应用的诞生本来就是为了发挥更多浏览器的效用,而不是每次都需要服务器来处理逻辑和数据。&/p&&p&但服务器当然也有它自己的效用。通过服务器端渲染可以直接把生成好的页面内容发送到客户端,由此你可以提高应用的性能,改善交互,并且也顺带解决了SEO和可访问性的问题。&/p&&p&服务器端渲染对于一些以内容为主的站点至关重要,而对于一些需要登录使用的Web App 并且不担心SEO的站点就不是那么有用了。所以大多数的开发者只觉得服务器端渲染只能算一个Nice-to-have的特性。&/p&&p&&strong&Code splitting代码拆分/按需加载&/strong&&/p&&p&虽然JavaScript是一个已有十多年历史的语言,JS应用在工程化方面的发展才刚刚萌芽。所以绝大多数的应用还是把打包好的所有代码直接发给客户端。&/p&&p&Code splitting 可以将你的代码拆分,只在客户端加载真正需要的使用的代码,由此可以极大地提高性能。&/p&&p&&strong&Optimistic Updates即时更新&/strong&&/p&&p&一些复杂的JavaScript应用有着大量的客户端服务器交互。通过Optimistic Updates技术,客户端可以无需等待服务器的响应,直接显示出交互的结果,之后再处理服务器与客户端直接不同步的数据。&/p&&p&&strong&Hot Module Reloading模块热重载&/strong&&/p&&p&Hot Module Reloading指的就是在开发过程中,你修改代码之后无需刷新浏览器页面,马上就能看到改变后的效果。这也是为什么很多开发者大爱这一特性的原因。&/p&&p&&strong&Time-Travel Debugging&/strong&&/p&&p&Time-Travel Debugging是一种新的调试模式,指的是在调试使用Redux一类状态管理的应用时,模拟应用在各个不同状态的改变。&/p&&p&&strong&Real-Time Operations实时交互&/strong&&/p&&p&随着浏览器日趋强大,网速日益提升。实时交互的特性会越来越普遍。(例如知乎不用刷新页面就可以收到新提醒的这类特性)&/p&&p&&strong&Dead Code Elimination冗余代码消除&/strong&&/p&&p&现在,一方面你可以让客户端按需加载代码,另外一方面,你也可以直接在构建过程中无用的代码。这部分内容其实在本专栏的&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&JavaScript 模块化入门Ⅱ:模块打包构建&/a&中介绍过。&/p&&p&&strong&Progressive Enhancement渐进式增强&/strong&&/p&&p&JavaScript 的各种特性确实很酷。但是想象一下你的应用如果运行在一个很破的设备或很差的网络中会怎么样。所以我们就需要一种渐进式增强的设计,先加载你应用最基本最主要的功能,然后再逐步加载完毕。(类似于一些网站提供的基本版/极速版)&/p&&p&特性排名:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-4d5d8ad0c2dbee910f6ddd_b.jpg& data-rawwidth=&986& data-rawheight=&527& class=&origin_image zh-lightbox-thumb& width=&986& data-original=&https://pic4.zhimg.com/v2-4d5d8ad0c2dbee910f6ddd_r.jpg&&&/figure&&h2&观点&/h2&&ul&&li&现在开发JavaScript有些过于复杂了&ul&&li&通过整个调查我们很容易就能发现这一点&/li&&/ul&&/li&&li&JavaScript被过度使用了&ul&&li&网页中是否过多地使用了JS?这一点JS程序员肯定不会同意&/li&&/ul&&/li&&li&JavaScript的发展变化实在是太快了&ul&&li&等你刚掌握了Grunt,Gulp火了,等你刚学会Gulp,大家又开始用Webpack了&/li&&/ul&&/li&&li&我愿意选择JS作为我最主要的编程语言&ul&&li&JS的名声一直不怎么好(在某些人眼里是迫不得已才会去使用的语言),但在今天大多数开发者不是因为他们不得不使用JS,而是他们真的愿意。&/li&&/ul&&/li&&li&JavaScript前途一片大好&ul&&li&JavaScript虐我千百遍,我待JavaScript如初恋,绝大多数的开发者还是很看好JS的发展前景的。&/li&&/ul&&/li&&li&我很享受用JavaScript开发App&ul&&li&JavaScript确实是一门很有趣的语言&/li&&/ul&&/li&&li&这份调查问卷真**长!&ul&&li&(哭,我写的都快累死了!)&/li&&/ul&&/li&&/ul&&h2&附录:&/h2&&ul&&li&&a href=&https://link.zhihu.com/?target=http%3A//stateofjs.yubolun.com/2016/profiles/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&受访者背景分布&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//stateofjs.yubolun.com/2016/conclusion/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&获取原始数据和结论&/a&&/li&&/ul&&p&我不生产观点,我只是观点的搬运工。所以麻烦撕哪种语言哪种框架好不要来找我,本文不代表个人意见,虽然我支持React/Vue/Webpack,大家喜欢的我都喜欢。JavaScript是最好的语言,但是我真的不是来和任何人撕的!&/p&&p&个人水平有限,文中包含一些我几乎没听过的术语词汇,所以还希望有了解的大大能够多多指点指正。&/p&&p&欢迎在评论区参与讨论!也可以推荐你喜欢的JavaScript生态中好用好玩的东西!&/p&&br&&h2&推荐阅读&/h2&&p&&b&学习方法&/b&&/p&&ul&&li&&a href=&https://zhuanlan.zhihu.com/p/?refer=icode& class=&internal&&在2016年如何学习JavaScript? - 从零学习前端开发 - 知乎专栏&/a&&br&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/?refer=icode& class=&internal&&6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.) - 从零学习前端开发 - 知乎专栏&/a&&br&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&自学前端开发:代码之外需要关注的问题&/a&&br&&/li&&/ul&&br&&p&&b&成功案例&/b&&/p&&ul&&li&&a href=&https://link.zhihu.com/?target=https%3A//chunge16.github.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&科班狗的前端之路&/a&&br&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/?refer=icode& class=&internal&&非计算机专业出身的我是如何在两年内成长为前端工程师的 - 从零学习前端开发 - 知乎专栏&/a&&br&&/li&&/ul&&br&&p&&b&如果你想要完整的学习Web开发&/b&&/p&&ul&&li&&a href=&https://zhuanlan.zhihu.com/p/?refer=icode& class=&internal&&Come on Baby! 你也可以成为Web开发工程师!——Web开发工程师完全成长指南 - 从零学习前端开发 - 知乎专栏&/a&&br&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/?refer=icode& class=&internal&&如何在一年之内通过自学找到Web开发工作 - 从零学习前端开发 - 知乎专栏&/a&&br&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/?refer=icode& class=&internal&&前端学习路径 - 余博伦的文章 - 知乎专栏&/a&&br&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/?refer=icode& class=&internal&& Web 开发者路线图 - 从零学习前端开发 - 知乎专栏&/a&&/li&&/ul&&p&&b&如果你想要免费系统地学习Web开发&/b&&/p&&p&&a href=&https://zhuanlan.zhihu.com/p/?refer=icode& class=&internal&&全世界学习Web开发的最好方式-FreeCodeCamp学习参考资料 - 从零学习前端开发 - 知乎专栏&/a&&/p&&br&&h2&号外!号外!&/h2&&p&从零学习前端开发有自己的QQ群啦!&/p&&p&群号:&a href=&tel:&&&/a&&/p&&p&点击链接加入群【从零学习前端开发】:&a href=&https://link.zhihu.com/?target=https%3A//jq.qq.com/%3F_wv%3DD41Qjx0t& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&加群链接&/a&&/p&&p&验证问题:想学啊你?答案:&b&我教你啊&/b&&/p&&p&意思就是输入答案四个字:&b&我教你啊&/b&&/p&&p&就可以入群了!就是这么简单直接!不要再问我啦!&/p&&p&我会在群内不定期分享各类前端学习资源,也会偶尔布置实践小作业供大家一同交流学习袄,以后还会陆续开展各类活动~&/p&
官网:发起人:整理翻译:我已委托 为我的文章进行维权行动。如需转载请访问
获得合法授权。有人认为JavaScript是最好的语言,有人认为它一团糟。可按照C++之父的话来讲:世界…
&figure&&img src=&https://pic4.zhimg.com/v2-4bcb14fc897ab7bae5624_b.jpg& data-rawwidth=&1089& data-rawheight=&525& class=&origin_image zh-lightbox-thumb& width=&1089& data-original=&https://pic4.zhimg.com/v2-4bcb14fc897ab7bae5624_r.jpg&&&/figure&&p&这两天 GitHub 对其官网进行了改版,紧接着又发布了一年一度的开源报告,我们程序员比较关心之后的趋势是什么,而 GitHub 毫无疑问代表了全世界编程领域的趋势,我们不妨先来解读下这份报告,然后再解答下你们关注的标题的答案。&br&&/p&&br&&p&事先声明,本篇文章的一些数据完全来自这份报告,地址在这里:&/p&&br&&p&&a href=&http://link.zhihu.com/?target=https%3A//octoverse.github.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GitHub Octoverse 2016&/a&&/p&&br&&br&&h2&1. 最流行的开源项目&/h2&&p&首先发布的是过去一年在 GitHub 上最流行的开源项目,见下图:&/p&&br&&figure&&img src=&https://pic4.zhimg.com/v2-5bd8a450dd6e78b48f3efc7_b.jpeg& data-rawwidth=&1327& data-rawheight=&1205& class=&origin_image zh-lightbox-thumb& width=&1327& data-original=&https://pic4.zhimg.com/v2-5bd8a450dd6e78b48f3efc7_r.jpg&&&/figure&&br&&p&可以看到其中有不少是我在之前 GitHub 系列文章里介绍过的,如 awesome、free-program-books、react-native、on-my-zsh 等,不过令我没想到的是 lantern 竟然也入选了,足以说明全世界人们对自由上网的渴望,关于 lantern 是什么我不多说了,自己去了解吧。&/p&&br&&br&&h2&2. 最受欢迎的编程语言&/h2&&p&这个世界有多少种编程语言你们知道么?我想没人说得清楚,GitHub 给出了答案。GitHub 上所有的开源项目包含了 316 种编程语言。不说不知道,一说吓一跳,要知道这世界上只有 226 个国家和地区,编程语言的数量超出了世界上国家的数量,有时候就在想,那么多不为人知的编程语言都是什么人在用?&/p&&br&&p&要问 2016 年最受欢迎的编程语言是什么?同样 GitHub 也给出了答案。以下是 GitHub 根据过去 12 月提交的 PR 数量来排名的,虽然不完全准确,但是 PR 起码代表了项目的热度与欢迎度,还是值得可信的:&/p&&br&&br&&figure&&img src=&https://pic2.zhimg.com/v2-1c589fffcfd7d_b.jpeg& data-rawwidth=&1122& data-rawheight=&1199& class=&origin_image zh-lightbox-thumb& width=&1122& data-original=&https://pic2.zhimg.com/v2-1c589fffcfd7d_r.jpg&&&/figure&&br&&p&可以看到排名第一的是 JavaScript 。我想有几方面的原因吧,一是本来 GitHub 上早期的一些开源项目都是 web 前端相关的,二是随着移动端各种跨平台框架的需求,js 被予以重任,如 React Native、weex 等,三是 js 领域各种框架层出不穷,如 vue.js、angular.js、react.js 等,所以 JavaScript 排名第一并不是很意外。所以有对 web 前端感兴趣的同学,js 是必备技能,想往这方面发展依然热度不减,而事实上国内需求目前对有经验的 web 前端工程师确实很缺乏,很多时候钱多活少离家近都招不到人。&/p&&br&&p&另外老牌语言 Java 依然能排名第二蛮意外的,我想这其中很大部分是因为 Android 的发展让 Java 焕发了第二春。&/p&&br&&p&紧接着是 Python、Ruby、PHP,这三种都是属于动态语言,对于我们 Android 开发所用的 Java 静态语言是不一样的,之前有人问过我想学习一门除了 Java 之外的语言,如果实在感兴趣的话我就建议学习下 Ruby 或者 Python ,能从中了解到很多 Java 层面没接触过的知识。另外都说 PHP 是世界上最好的编程语言,这排名名不副实啊!&/p&&br&&p&另外这份排名很有意思,元老级编程语言 C++、C 几乎每年都上榜,所以根本不用担心自己用的编程语言会过时,如果真那样的话 C++、C 那些程序员早都丢饭碗了。&/p&&br&&p&最后一经出来就被热捧的 Swift 排名有点对不起大家对它的期待,今年仍然比不过亲兄弟的 Objective C ,我觉得很大原因是因为亲爹 Apple 没有让开发者们强制使用 Swift,不过增长倒是很迅速,增长了 262%,相信这增长速度加上有个强大的爹,它的发展还是很期待的,只不过听说现在甚至还在改语法,所以还没有完全成熟,不要过于这么快就报太大的期待,不过如果 iOS 开发者们到现在还没有学习甚至了解就说不过去了。&/p&&br&&p&所以,2016 年最受欢迎的编程语言是 JavaScript !&/p&&br&&p&PS:作为 Android 开发者也蛮高兴的,毕竟我们所用的编程语言 Java 是 JavaScript 他哥!&/p&&br&&br&&h2&3. 开源贡献最多的组织&/h2&&p&打死我都想不到 2016 年对开源贡献最多的竟然是微软,一向封闭为主的微软今年发力开源社区,竟然超越了 Google、Facebook,加上国内很大巨头也纷纷在开源社区发力,别的不说,就说 Android 界吧,今年包括腾讯、阿里等纷纷推出各自的开源项目,可能真的说明拥抱开源,才是王道吧!&/p&&br&&br&&figure&&img src=&https://pic4.zhimg.com/v2-f0b59affde_b.jpeg& data-rawwidth=&529& data-rawheight=&700& class=&origin_image zh-lightbox-thumb& width=&529& data-original=&https://pic4.zhimg.com/v2-f0b59affde_r.jpg&&&/figure&&br&&h2&4. GitHub 新增用户&/h2&&p&GitHub 已经有超过 520 万的用户和超 30 万的组织。而今年,中国是新用户增长最多的国家,比 15 年增长快翻了一番,而这其中,身为一个 Google、GitHub 真爱粉,我觉得我也出了一把力(装逼完成,逃...)&/p&&br&&figure&&img src=&https://pic4.zhimg.com/v2-ec9cc83dac5b60a8be22957_b.jpeg& data-rawwidth=&887& data-rawheight=&341& class=&origin_image zh-lightbox-thumb& width=&887& data-original=&https://pic4.zhimg.com/v2-ec9cc83dac5b60a8be22957_r.jpg&&&/figure&&br&&p&当然还有很多其他有意思的数据,这里就不一一详细介绍了,感兴趣的不妨到这里去看下。&/p&&br&&p&&a href=&http://link.zhihu.com/?target=https%3A//octoverse.github.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GitHub Octoverse 2016&/a&&/p&&br&&p&最后,GitHub 的这份报告代表着过去的数据,不过对于我们对未来的技术趋势判断有一定参考意义,所有编程从业者都有必要关注下这份报告,当然文中涉及到的一些观点纯属个人,不代表官方与任何组织,欢迎交流。&/p&&br&&br&&p&&b&推荐阅读&/b&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com/github//learn-github-from-zero1/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&从0开始学习 GitHub 系列之「初识 GitHub」&/a&&br&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com/github//learn-github-from-zero1/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&从0开始学习 GitHub 系列之「初识 GitHub」&/a&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com/github//learn-github-from-zero2/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&从0开始学习 GitHub 系列之「加入 GitHub」&/a&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com/github//learn-github-from-zero3/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&从0开始学习 GitHub 系列之「Git 速成」&/a&&br&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com/github//learn-github-from-zero4/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&从0开始学习 GitHub 系列之「向GitHub 提交代码」&/a&&br&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com/github//learn-github-from-zero5/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&从0开始学习 GitHub 系列之「Git 进阶」&/a&&br&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com/github//learn-from-github-from-zero6/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&从0开始学习 GitHub 系列之「团队合作利器 Branch」&/a&&br&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com/github//learn-github-from-zero7/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&如何发现优秀的开源项目?&/a&&/p&&br&&br&&blockquote&&b&本文原创发布于微信公众号 AndroidDeveloper,不仅是Android原创干货分享,也许是最有人情味的技术公众号,转载请务必注明出处!&/b&&/blockquote&&br&&br&&br&&p&「&a href=&http://link.zhihu.com/?target=http%3A//gold.xitu.io/welcome/android%3Futm_source%3Dzhihu_stormzhang%26utm_medium%3Dword%26utm_content%3Dgaoshou%26utm_campaign%3Dq3_personal& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&掘金&/a&」是一个高质量的技术社区,从 RxJava 到 React Native,性能优化到优秀开源库,让你不错过 Android 开发的每一个技术干货。各大应用市场搜索「&a href=&http://link.zhihu.com/?target=http%3A//gold.xitu.io/welcome/android%3Futm_source%3Dzhihu_stormzhang%26utm_medium%3Dword%26utm_content%3Dgaoshou%26utm_campaign%3Dq3_personal& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&掘金&/a&」,技术干货尽在掌握中。&/p&&figure&&img src=&https://pic1.zhimg.com/f771e90ce3334fe3cfdf1baa28b0dfa8_b.png& data-rawwidth=&1200& data-rawheight=&666& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&https://pic1.zhimg.com/f771e90ce3334fe3cfdf1baa28b0dfa8_r.jpg&&&/figure&
这两天 GitHub 对其官网进行了改版,紧接着又发布了一年一度的开源报告,我们程序员比较关心之后的趋势是什么,而 GitHub 毫无疑问代表了全世界编程领域的趋势,我们不妨先来解读下这份报告,然后再解答下你们关注的标题的答案。 事先声明,本篇文章的一些…
&blockquote&&p&React.js 作为前端框架的后起之秀,却在2015年携着虚拟 DOM,组件化,单向数据流等利器,给前端 UI 构建掀起了一波声势浩大的函数式新潮流。新鲜出炉的一篇 React.js 最佳实践,基本涵盖了所有的 React.js 生态周边,可用于实践参考。文章不仅表明了 Flux 经常被滥用的观点,也推荐开发者使用 Redux 作为 JavaScript 的可预测状态容器,并且提出保持状态扁平化和使用 Immutable.js 等数据处理解决方案。与此同时,也从高阶组件,组件测试以及组件级别热重载等方面提供了建议,当然也涉及了 Webpack,HTTP 2,使用 ES2015 乃至 Linters 等代码层面的建议。&/p&&/blockquote&&br&&br&不得不吐槽知乎编辑器的渣渣功能,更佳阅读效果,可以到我的博客看&b&双语版:&a href=&//link.zhihu.com/?target=http%3A//blog.jimmylv.info/-React.js-Best-Practices-for-2016& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【译】展望2016,React.js 最佳实践 (中英对照版)&/a&&/b&&br&&br&&figure&&img src=&https://pic1.zhimg.com/69f338a90e10d8ee033390_b.png& data-rawwidth=&1440& data-rawheight=&775& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&https://pic1.zhimg.com/69f338a90e10d8ee033390_r.png&&&/figure&&br&------&br&&br&&b&&br&【译】展望2016,React.js 最佳实践&/b&&p&原文地址:&&a href=&//link.zhihu.com/?target=https%3A//blog.risingstack.com/react-js-best-practices-for-2016/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&React.js Best Practices for 2016&/a&&&/p&&br&&p&过去的2015年,&strong&&a href=&//link.zhihu.com/?target=http%3A//a%2520javascript%2520library%2520for%2520building%2520user%2520interfaces/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&React&/a&&/strong& 在全世界范围都是一派欣欣向荣的景象,开发者会议无一不热衷于这个话题。在过去一年中发生了很多重要的里程碑事件,更多详情可以查看我们关于 &a href=&//link.zhihu.com/?target=https%3A//blog.risingstack.com/react-in-2015/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&React in 2015&/a& 的总结。&/p&&br&&p&在新的2016年里,最有趣的问题来了:&strong&我们该如何开发一个应用&/strong&,有什么推荐使用的库?&/p&&blockquote&&p&作为一名长时间使用 React.js 的开发者来说,我对这个问题有自己的答案以及最佳实践,但也有可能你不会完全认同。我也非常乐于倾听你的想法和观点:请留言以便讨论。&/p&&/blockquote&&figure&&img src=&https://pic3.zhimg.com/be3fde2bd364b1b66375e7a_b.png& data-rawwidth=&600& data-rawheight=&167& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic3.zhimg.com/be3fde2bd364b1b66375e7a_r.png&&&/figure&&br&&p&如果你才刚刚开始学习 React.js,可以查看我们的 &a href=&https://www.zhihu.com/question//answer/The%20React.js%20Way:%20Getting%20Started%20Tutorial& class=&internal&&React.js 教程&/a&,或者 Pete Hunt 所写的 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20petehunt/react-howto:%20Your%20guide%20to%20the%20(sometimes%20overwhelming!& class=&internal&&React howto&/a& React ecosystem.)。&/p&&br&&b&数据处理&/b&&br&&br&&p&在 React.js 应用中处理数据轻而易举,与此同时亦充满挑战。这是因为你可以通过各种方式将属性数据传递给 React 组件,并从中构建渲染树;然而这种方式也并非那么显而易见,到底该如何更新视图。2015之初诞生了很多不同 Flux 库,并不断产出了更加实用的响应式方案。&/p&&br&&p&让我们看看现在的情况:&/p&&br&&br&&b&Flux&/b&&br&&br&&i&根据我们的经验,Flux 经常被滥用,(这意味着大家总是在不需要的时候就用上它)。&/i&&br&&p&Flux 提供了一种非常清晰的方式来存储和更新应用状态,并且只会在必要的时候才触发页面渲染。&/p&&p&Flux 致力于&strong&应用的全局状态管理&/strong&,比如:管理已登录用户状态,路由状态,或者是活跃账户状态,但若是用来管理临时数据或者本地数据,瞬间就变成了痛苦。&/p&&br&&p&我们不推荐使用 Flux 来管理路由相关的数据,比如 /items/:itemId。而只是获取路由数据并存储在组件的 state 之中。在这种情况下,它会在组件消失之后一起被销毁。&/p&&br&&p&&em&如果你想了解更多关于 Flux 的信息,&a href=&//link.zhihu.com/?target=http%3A//the%2520evolution%2520of%2520flux%2520frameworks/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Evolution of Flux Frameworks&/a& 非常值得一读。&/em&&/p&&br&&br&&b&使用 Redux&/b&&blockquote&&p&Redux 是一个 &i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i& 应用的可预测状态容器。&/p&&/blockquote&&br&&p&如果你觉得需要 Flux 或者一种类似的解决方案,你应该了解一下 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20reactjs/redux:%20Predictable%20state%20container%20for%20JavaScript%20apps& class=&internal&&redux&/a&,以及学习 &a href=&//link.zhihu.com/?target=https%3A//twitter.com/dan_abramov& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dan Abramov&/a& 的&a href=&//link.zhihu.com/?target=http%3A//getting%2520started%2520with%2520redux/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Getting started with redux&/a& 课程,这能够迅速提高你的开发技能。&/p&&blockquote&&p&Redux 延续并改进了 Flux 的思想,并从 Elm 架构中取经,规避了 Flux 的复杂度。(译者注:Elm 是一门面向 Web 的函数式编程语言,致力于改善客户端 Web 编程体验。)&/p&&/blockquote&&br&&b&保持状态扁平化 &/b&&br&&p&API 经常会返回嵌套资源。这在 Flux 或基于 Redux 的架构中处理起来会非常困难。我们推荐使用 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20gaearon/normalizr:%20Normalizes%20nested%20JSON%20according%20to%20a%20schema& class=&internal&&normalizr&/a& 之类的库将数据进行扁平化处理,&strong&保持状态尽可能地扁平化&/strong&。&/p&&br&&p&示意:&/p&&div class=&highlight&&&pre&&code class=&language-text&&const data = normalize(response, arrayOf(schema.user))
state = _.merge(state, data.entities)
&/code&&/pre&&/div&&p&&em&(我们使用 &a href=&//link.zhihu.com/?target=http%3A//isomorphic-fetch/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&isomorphic-fetch&/a& 来与 APIs 进行交互)&/em&&/p&&br&&br&&b&使用 immutable 状态&/b&&blockquote&&p&共享的可变性状态乃万恶之源。 —— &em&Pete Hunt, React.js Conf 2015&/em&&/p&&/blockquote&&figure&&img src=&https://pic1.zhimg.com/adf2f172e2c48_b.png& data-rawwidth=&629& data-rawheight=&187& class=&origin_image zh-lightbox-thumb& width=&629& data-original=&https://pic1.zhimg.com/adf2f172e2c48_r.png&&&/figure&&br&&p&&a href=&//link.zhihu.com/?target=http%3A//immutable%2520object/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&不可变对象&/a&是一种在创建之后就不可修改的对象。不可变对象可以让我们免于痛楚,并通过引用级别的比对检查来&strong&改善渲染性能&/strong& 。比如说在 shouldComponentUpdate 中:&/p&&br&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&nx&&shouldComponentUpdate&/span&&span class=&p&&(&/span&&span class=&nx&&nexProps&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&c1&&// instead of object deep comparsion&/span&
&span class=&k&&return&/span& &span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&props&/span&&span class=&p&&.&/span&&span class=&nx&&immutableFoo&/span& &span class=&o&&!==&/span& &span class=&nx&&nexProps&/span&&span class=&p&&.&/span&&span class=&nx&&immutableFoo&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&br&&p&&strong&如何在 &i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i& 中实现不可变呢?&/strong&&/p&&br&&p&最痛苦的方式就是小心为之,示例代码如下,你需要在单元测试中通过 &a href=&//link.zhihu.com/?target=http%3A//deep-freeze-node/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&deep-freeze-node&/a& 来反复验证。(在修改之前冻结,并在结束后验证结果。)&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&k&&return&/span& &span class=&p&&{&/span&
&span class=&p&&...&/span&&span class=&nx&&state&/span&&span class=&p&&,&/span&
&span class=&nx&&foo&/span&
&span class=&p&&}&/span&
&span class=&k&&return&/span& &span class=&nx&&arr1&/span&&span class=&p&&.&/span&&span class=&nx&&concat&/span&&span class=&p&&(&/span&&span class=&nx&&arr2&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&br&&p&相信我,这是最平淡无奇的例子了。更简单也更自然的方式就是使用 &a href=&//link.zhihu.com/?target=http%3A//immutable.js/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Immutable.js&/a&。&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&import { fromJS } from 'immutable'
const state = fromJS({ bar: 'biz' })
const newState = foo.set('bar', 'baz')
&/code&&/pre&&/div&&br&&p&Immutable.js 非常之快,背后理念也异常漂亮。哪怕你并不想使用它,我也推荐阅读这个由 &a href=&//link.zhihu.com/?target=https%3A//twitter.com/leeb& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Lee Byron&/a& 所制作的视频 &a href=&//link.zhihu.com/?target=https%3A//www.youtube.com/watch%3Fv%3DI7IdS-PbEgI& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Immutable Data and React&/a&。视频对于 Immutable.js 的工作原理有着非常深刻的讲解。&/p&&br&&b&观察式与响应式方案&/b&&br&&br&&p&如果你不喜欢 Flux/Redux 或者只是想要更加 reactive,不要失望!这儿有很多其他数据处理的解决方案。这就有一个相关库的简要列表供你参考:&/p&&ul&&li&&a href=&//link.zhihu.com/?target=http%3A//cycle.js/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cycle.js&/a&&em&(“A functional and reactive &/em&&i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&em& framework for cleaner code”)&/em&&/li&&li&&a href=&https://www.zhihu.com/question//answer/GitHub%20-%20fdecampredon/rx-flux:%20The%20Flux%20architecture%20with%20RxJS& class=&internal&&rx-flux&/a&&em&(“The Flux architecture with RxJS”)&/em&&/li&&li&&a href=&https://www.zhihu.com/question//answer/GitHub%20-%20acdlite/redux-rx:%20RxJS%20utilities%20for%20Redux.& class=&internal&&redux-rx&/a&&em&(“RxJS utilities for Redux.”)&/em&&/li&&li&&a href=&//link.zhihu.com/?target=http%3A//why%2520mobservable/%3F& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&mobservable&/a&&em&(“Observable data. Reactive functions. Simple code.”)&/em&&/li&&/ul&&b&&br&&br&路由 &/b&&br&&p&几乎所有的客户端应用都或多或少需要使用路由。如果你在浏览器中使用 React.js,你就会在挑选库的时候碰到这个分歧点。我们的选择是出自优秀的 &a href=&//link.zhihu.com/?target=http%3A//xn--rackt%github-s2a/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&rackt&/a& 社区的 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20reactjs/react-router:%20A%20complete%20routing%20solution%20for%20React.js& class=&internal&&react-router&/a&。Racket 给 React.js 的拥簇者带来了很多高质量资源。&/p&&br&&p&你可以查看他们的&a href=&//link.zhihu.com/?target=http%3A//react-router/docs%2520at%2520master%%25B7%2520reactjs/react-router%%25B7%2520GitHub& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&文档&/a&以便于集成 react-router,但是更重要的是:如果你使用 Flux/Redux,我们建议你将路由状态和你的 store 或全局状态&strong&保持同步&/strong&。&/p&&br&&p&同步的路由状态可以帮助你对 Flux/Redux 的 Actions 所提供的路由行为有所控制,并且能够在组件中读取路由状态和参数。&/p&&br&&p&Redux 用户可以通过 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20reactjs/react-router-redux:%20Ruthlessly%20simple%20bindings%20to%20keep%20react-router%20and%20redux%20in%20sync& class=&internal&&redux-simple-router&/a& 这个库轻松实现它。&/p&&br&&br&&b&代码分割,惰性加载&/b&&br&&br&&p&只有一小部分 webpack 用户知道应用代码是可以分割的,将 bundler 的输出拆分成多个 &em&&i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/em& 块:&/p&&div class=&highlight&&&pre&&code class=&language-text&&require.ensure([], () =& {
const Profile = require('./Profile.js')
this.setState({
currentComponent: Profile
&/code&&/pre&&/div&&br&&p&这在大型应用中会非常有用,因为在每次部署之后,用户浏览器就&strong&没有必要下载那些很少用到的代码&/strong&,比如 profile 页面。&/p&&br&&p&更多代码块将导致更多 HTTP 请求 —— 但是使用 &a href=&//link.zhihu.com/?target=http%3A//http/2%2520Frequently%2520Asked%2520Questions& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HTTP/2 multiplexed&/a& 的话就不成问题。结合 &a href=&//link.zhihu.com/?target=http%3A//optimizing%2520caching/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&chunk hashing&/a&,你也可以在代码改变之后优化缓存命中率。(译者注:终端用户访问加速节点时,如果该节点有缓存住了要被访问的数据时就叫做命中,如果没有的话需要回原服务器获取,就是没有命中。)&/p&&br&&p&react-router 的下个版本就将在代码分割这方面提供更多帮助。&/p&&br&&p&想要了解 react-router 的未来走向,可以查看 &a href=&//link.zhihu.com/?target=https%3A//twitter.com/ryanflorence& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ryan Florence&/a& 所写的这篇博文: &a href=&//link.zhihu.com/?target=https%3A//medium.com/%40ryanflorence/welcome-to-future-of-web-application-delivery-f%23.vuf3e1nqi& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Welcome to Future of Web Application Delivery&/a&。&/p&&b&&br&&br&组件 &/b&&br&&p&大部分人都对 JSX 存有怨言。首先,你需要知道的是这在 React 中并不是必须的。在最后,JSX 都会通过 Babel 被编译成 &em&&i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/em&。你可以直接编写 &em&&i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/em& 来替代 JSX,但是在处理 HTML 的时候使用 JSX 会感觉更加自然。&/p&&br&&p&特别是对于不懂技术的人来说,他们依然可以理解和修改必要的部分。&/p&&blockquote&&p&JSX 是一种与 XML 类似的 &em&&i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/em& 语法扩展。你可以通过一个简单的 JSX 语法转换器来编译 React。 —— &a href=&//link.zhihu.com/?target=http%3A//jsx%2520in%2520depth/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JSX in depth&/a&&/p&&/blockquote&&p&如果你想要了解更多关于 JSX 的信息,可以查看 &a href=&//link.zhihu.com/?target=http%3A//jsx%2520looks%2520like%2520an%2520abomination%%25A2%25E2%2582%25AC%25E2%20javascript%2520scene/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JSX Looks Like An Abomination - But it’s Good for You&/a& 这篇文章。&/p&&br&&br&&b&使用 Class&/b&&br&&br&&p&React 和 ES2015 的 Class 语法搭配完美。&/p&&div class=&highlight&&&pre&&code class=&language-text&&class HelloMessage extends React.Component {
render() {
return &div&Hello {this.props.name}&/div&
&/code&&/pre&&/div&&br&&p&我们喜欢&a href=&https://www.zhihu.com/question//answer/Structuring%20React%20Applications:%20Higher-Order%20Components& class=&internal&&高阶组件&/a&更胜于 mixins,所以对于我们来说,保留 createClass 就更像一个语法问题而不是技术问题。我们相信使用 createClass 而不是 React.Component 绝对无可厚非,反之亦然。&/p&&br&&br&&b&属性类型&/b&&br&&br&&p&如果你在2016年依然没有检查 properties,那么你应该从现在开始做起,这将为你节省大量时间,相信我。&/p&&div class=&highlight&&&pre&&code class=&language-text&&MyComponent.propTypes = {
isLoading: PropTypes.bool.isRequired,
items: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
name: PropTypes.string.isRequired,
).isRequired
&/code&&/pre&&/div&&br&&p&当然,验证 Immutable.js 所编写的 properties 也是可能的,可以使用&a href=&//link.zhihu.com/?target=http%3A//react-immutable-proptypes/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&react-immutable-proptypes&/a&。&/p&&br&&br&&b&高阶组件 &/b&&br&&p&目前来说,&a href=&//link.zhihu.com/?target=http%3A//mixins%2520are%2520dead.%2520long%2520live%2520composition/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&mixins 已死&/a&,而且在 ES6 Class 组件中已经不再被支持,我们应当寻找不同的替代方案。&/p&&br&&p&&strong&那什么是高阶组件呢?&/strong&&/p&&div class=&highlight&&&pre&&code class=&language-text&&PassData({ foo: 'bar' })(MyComponent)
&/code&&/pre&&/div&&br&&p&本质上来说,你可以由原始组件创造一个新的组件并且扩展它的行为。你可以在多种情况下使用它,比如授权:requireAuth({ role: 'admin' })(MyComponent) &em&(检查上层组件中的用户,若是未登录则需要重定向)&/em&,或者是连接你的组件和 Flux/Redux 仓库。&/p&&br&&p&在RisingStack,我们也将数据获取和类似 Controller 的逻辑分割成高阶组件,并保持视图层尽可能简单。&/p&&br&&b&测试&/b&&br&&br&&p&在开发周期中,维持测试的高覆盖率是非常重要的一部分。幸运的是, React.js 社区诞生了很多优秀的库可以帮助我们达到这一点。&/p&&br&&br&&b&组件测试&/b&&br&&br&&p&我们最喜爱的库之一是由 AirBnb 所开发的 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20airbnb/enzyme:%20JavaScript%20Testing%20utilities%20for%20React& class=&internal&&enzyme&/a&,可用于组件测试。非常神奇的是,它的浅渲染特性可以对组件的逻辑及其渲染输出进行测试。尽管它还不能替代你的 selenium 测试,但是将前端测试提升到了一个新的水平。&/p&&div class=&highlight&&&pre&&code class=&language-text&&it('simulates click events', () =& {
const onButtonClick = sinon.spy()
const wrapper = shallow(
&Foo onButtonClick={onButtonClick} /&
wrapper.find('button').simulate('click')
expect(onButtonClick.calledOnce).to.be.true
&/code&&/pre&&/div&&br&&p&看起来就非常简洁,不是么?你在使用 chai 作为测试断言库嘛?相信你会喜欢 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20producthunt/chai-enzyme:%20Chai.js%20assertions%20and%20convenience%20functions%20for%20testing%20React%20Components%20with%20enzyme& class=&internal&&chai-enyzime&/a& 的!&/p&&br&&br&&b&Redux 测试&/b&&br&&br&&p&&strong&测试一个 reducer&/strong& 非常简单,它响应新到来的 actions,并且将原来的状态进行更新:&/p&&div class=&highlight&&&pre&&code class=&language-text&&it('should set token', () =& {
const nextState = reducer(undefined, {
type: USER_SET_TOKEN,
token: 'my-token'
// immutable.js state output
expect(nextState.toJS()).to.be.eql({
token: 'my-token'
&/code&&/pre&&/div&&br&&p&&strong&测试 actions&/strong& 也很简单,但是异步 actions 就不太一样了。对于测试异步的 Redux actions 来说,我们推荐使用 &a href=&//link.zhihu.com/?target=http%3A//redux-mock-store/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&redux-mock-store&/a&,非常有帮助。&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&it('should dispatch action', (done) =& {
const getState = {}
const action = { type: 'ADD_TODO' }
const expectedActions = [action]
const store = mockStore(getState, expectedActions, done)
store.dispatch(action)
&/code&&/pre&&/div&&br&&p&更深度地了解 &a href=&//link.zhihu.com/?target=http%3A//rackt.org/redux/docs/recipes/WritingTests.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&redux 测试&/a&,可以查看官方文档。&/p&&br&&b&使用 npm&/b&&br&&br&&p&虽然 React.js 并不依赖代码打包工具就可以很好地工作,但我们还是推荐使用 &a href=&//link.zhihu.com/?target=http%3A//webpack%2520module%2520bundler/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Webpack&/a& 或者 &a href=&//link.zhihu.com/?target=http%3A//browserify/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Browserify&/a& 来发挥 &a href=&//link.zhihu.com/?target=http%3A//npm/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&npm&/a& 的能力。Npm 上满是高质量的 React.js 包,还可以帮你非常优雅地管理依赖。&/p&&br&&p&&em&(请不要忘记复用你自己的组件,这是一种绝佳的代码优化方式。)&/em&&/p&&br&&br&&b&Bundle 大小&/b&&br&&br&&p&这本身不是一个 React 相关的问题,但是大多数人都在打包他们的 React 应用,所以我认为提到这点很重要。当你打包源代码的时候,时刻警惕打包后的文件大小。为了&strong&保持体积最小化&/strong&,你应该考虑如何 require/import 依赖。&/p&&br&&p&对比以下代码片段,这两种不同的方式对输出的影响区别巨大:&/p&&div class=&highlight&&&pre&&code class=&language-text&&import { concat, sortBy, map, sample } from 'lodash'
import concat from 'lodash/concat';
import sortBy from 'lodash/sortBy';
import map from 'lodash/map';
import sample from 'lodash/sample';
&/code&&/pre&&/div&&br&&p&可以查看这篇文章 &a href=&//link.zhihu.com/?target=http%3A//reduce%2520your%2520bundle.js%2520file%2520size%2520by%2520doing%2520this%2520one%2520thing/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Reduce Your bundle.js File Size By Doing This One Thing&/a& 获取更多详情。&/p&&p&我们也喜欢将代码分离出至少 vendors.js 和 app.js 两个文件,因为 vendors 相对于我们的代码库来说更新不是那么频繁。&/p&&br&&p&将输出文件名称进行哈希化处理 &em&(Webpack 中的 chunk hash)&/em&,并使用长缓存,我们可以大大减少用户需要下载的代码大小。结合惰性加载,优化效果可想而知。&/p&&br&&p&如果你还不太熟悉 Webpack,可以查看这本优秀的 &a href=&//link.zhihu.com/?target=http%3A//introduction/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&React webpack 手册&/a&。&/p&&br&&br&&b&组件级别热重载&/b&&br&&br&&p&如果你曾经使用过热加载来编写单页面应用,当你在处理某些与状态相关的事情时,可能你就会明白当你在编辑器中点击保存,整个页面就重新加载了是多么令人讨厌。这样子就不得不重新点击一遍应用,重复如此会令人抓狂的。&/p&&br&&p&通过 React,在重载组件的同时&strong&保持组件状态&/strong&已经成为可能 —— 耶,从此不再痛苦!(没有蛀牙!)&/p&&br&&p&关于如何搭建热重载,可以参考 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20gaearon/react-transform-boilerplate:%20A%20new%20Webpack%20boilerplate%20with%20hot%20reloading%20React%20components,%20and%20error%20handling%20on%20module%20and%20component%20level.& class=&internal&&react-transform-boilerplate&/a&。&/p&&b&&br&&br&使用ES2015&/b&&br&&br&&p&前面有提到过,我们可以在 React.js 组件中使用 JSX,然后使用&a href=&//link.zhihu.com/?target=http%3A//babel%%%25B7%2520the%2520compiler%2520for%2520writing%2520next%2520generation%2520javascript/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Babel.js&/a&进行编译。&/p&&p&其实 Babel 的能力远不止如此,它也可以让我们现在就可以给浏览器编写 ES6/ES2015 代码。在 RisingStack,我们在服务器端和客户端都使用了 ES2015 特性,这都已经在最新的 LTS Node.js 版本中被实现了。&/p&&br&&figure&&img src=&https://pic2.zhimg.com/b7a6ddeafc51_b.png& data-rawwidth=&400& data-rawheight=&277& class=&content_image& width=&400&&&/figure&&br&&b&Linters&/b&&br&&br&&p&或许你已经给你的 &em&&i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/em& 代码制定了代码规范,但是你知道也有用于 React 的代码规范了吗?我们强烈推荐挑选一个并开始遵循它。&/p&&br&&p&在 RisingStack,我们也将 linters 强制运行在 CI 系统上,git push 亦然。可以试试 &a href=&//link.zhihu.com/?target=http%3A//pre-push/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&pre-push&/a& 或者 &a href=&//link.zhihu.com/?target=http%3A//pre-commit/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&pre-commit&/a&。&/p&&br&&p&我们使用标准的 &em&&i&&i&&i&&i&&i&&i&&i&&i&&i&&i&JavaScript&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/i&&/em& 代码风格,并使用了 &a href=&//link.zhihu.com/?target=http%3A//eslint-plugin-react/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&eslint-plugin-react&/a&对 React.js 代码进行规范 。&/p&&p&&em&(就是,我们不再使用分号。)&/em&&/p&&br&&br&&b&GraphQL 和 Relay&/b&&br&&br&&p&GraphQL 和 Relay 相对而言属于新技术,在 RisingStack,目前我们还没有在产品环境中使用它们,暂时保持关注。&/p&&br&&p&我们曾经写过一个 Relay 的 MongoDB ORM库,叫做 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20RisingStack/graffiti:%20Node.js%20GraphQL%20ORM& class=&internal&&graffiti&/a&,可以使用已有的 mongoose 模型直接创建一个 GraphQL 服务器。&/p&&br&&p&如果你想要学习这些新技术,我们建议你可以找来玩一玩。&/p&&br&&br&&b&尽情享用这些 React.js 最佳实践&/b&&br&&br&&p&有些突出的技术和库其实跟 React.js 并不相关 —— 但是保持视野开阔,关注社区的其他人都在做些什么。React 社区在2015年里就受到了 &a href=&https://www.zhihu.com/question//answer/GitHub%20-%20evancz/elm-architecture-tutorial:%20How%20to%20create%20modular%20Elm%20code%20that%20scales%20nicely%20with%20your%20app& class=&internal&&Elm 架构&/a& 的很多启发。&/p&&blockquote&&p&如果你知道其它在2016年必不可少的 React.js 工具,请留言让我们知道!&/p&&/blockquote&&br&-------&br&&br&&b&原作者: &a href=&//link.zhihu.com/?target=http%3A//xn--pter%2520mrton-rma8h34bia/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Péter Márton&/a&&/b&&br&&p&CTO at RisingStack, brewing beer with Node.js&/p&&p&&a href=&https://www.zhihu.com/question//answer/%5Bhttps://twitter.com/slashdotpeter%5D(https://twitter.com/slashdotpeter)& class=&internal&&https://twitter.com/slashdotpeter&/a&&/p&&br&
React.js 作为前端框架的后起之秀,却在2015年携着虚拟 DOM,组件化,单向数据流等利器,给前端 UI 构建掀起了一波声势浩大的函数式新潮流。新鲜出炉的一篇 React.js 最佳实践,基本涵盖了所有的 React.js 生态周边,可用于实践参考。文章不仅表明了 Flux …
代表公司去参加今年的 第二届前端开发者年度大会,散会的时候,Team 技术老大问我,今天感觉怎么样,有什么收获,当时就零零碎碎的回答了一些,不算完美;趁着还记得点什么,在这里做个自我回顾总结,谨代表个人见解,有不当之处,或若涉及图片隐私或者其它问题,烦请指正.&br&&br&==================================================&br&记得小时候写作文的时候,老师都会强调三要素:时间,地点,人物;那下面就从这三要素来作为时间线回顾:&br&&br&&b&时间&/b&:2016 - 03 - 19 &br&&b&地点&/b&:广州嘉裕太阳城广场三楼金逸国际影城四号厅&br&&b&演讲嘉宾&/b&:绝对的重量级人物,看图说话&br&&figure&&img src=&https://pic2.zhimg.com/aee8e8f10aaf40ef60f36bbe5d075281_b.png& data-rawwidth=&1292& data-rawheight=&1038& class=&origin_image zh-lightbox-thumb& width=&1292& data-original=&https://pic2.zhimg.com/aee8e8f10aaf40ef60f36bbe5d075281_r.png&&&/figure&&br&&b&感受下大会的现场:&/b&&br&&figure&&img src=&https://pic1.zhimg.com/71ffd09fce965a154581c_b.jpg& data-rawwidth=&1280& data-rawheight=&1280& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic1.zhimg.com/71ffd09fce965a154581c_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/35ccfe818ea290f315eab6e679dc6247_b.jpg& data-rawwidth=&1280& data-rawheight=&960& class=&origin_image zh-lightbox-thumb& width=&1280& data-orig}

我要回帖

更多关于 www.353ee.com 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信