WEB 前端的进化和 Unix 哲学

原创
2018/03/20 15:29
阅读数 189

背景

近期有不少的前端框架讨论

在前端框架的残酷生命周期下,我们该如何选择?

为什么我要从 Angular 迁移到 React 和 Redux ?

真实的世界

在阐述观点前, 大家应该先看看他们各自主页的第一句话和 Issues 对比(自行查看 closed issues)

Angular issues

One framework. Mobile & desktop

VUE issues

The Progressive JavaScript Framework

jQuery issues

jQuery is a fast, small, and feature-rich JavaScript library

React React 的各个部分是独立的, 没有汇总的 Issues

A JavaScript library for building user interfaces

毋庸置疑, 这都是流行项目, 每个都有巨量的使用者. 那么从他们的 Issues 和自述不难看出一个事实:

Framework 给你约束, 你的遇到的问题会很多, 通常你只能求助官方团队寻求解决方法, 还不一定能得到明确答复.

Library 给你自由, 你遇到的问题无论多少, 通常官方会给你明确的答复. 但需要你自己负责搭配使用.

Unix哲学

我对于这种讨论现象很是烦躁, 计算机编程技术已经发展这么多年, 最最基础的编程理念(法则)还没被大家普遍认同和遵守么?

关于Unix哲学

摘要:

  1. 清晰原则。 代码要写得尽量清晰,避免晦涩难懂。清晰的代码不容易崩溃,而且容易理解和维护。重视注释。不为了性能的一丁点提升,而大幅增加技术的复杂性,因为复杂的技术会使得日后的阅读和维护更加艰难。

  2. 模块原则。 每个程序只做一件事,不要试图在单个程序中完成多个任务。在程序的内部,面向用户的界面(前端)应该与运算机制(后端)分离,因为前端的变化往往快于后端。

  3. 组合原则。 不同的程序之间通过接口相连。接口之间用文本格式进行通信,因为文本格式是最容易处理、最通用的格式。这就意味着尽量不要使用二进制数据进行通信,不要把二进制内容作为输出和输入。

  4. 优化原则。 在功能实现之前,不要考虑对它优化。最重要的是让一切先能够运行,其次才是效率。"先求运行,再求正确,最后求快。"(Make it run, then make it right, then make it fast.)90%的功能现在能实现,比100%的功能永远实现不了强。先做出原型,然后找出哪些功能不必实现,那些不用写的代码显然无需优化。目前,最强大的优化工具恐怕是Delete键。

我的观点

The library is first

如果上面这些还不能让你认同这个观点, 那么去 Github 看看四大项目的测试代码是怎么写的吧, 看看谁的测试里面包含现实意义的代码多, 谁的测试代码中出现毫无现实意义的代码多.

技术探讨

我们讨论点干货, 即便有些我自己都没有实现. 我只讨论 WEB 场景下的基础技术.

DOM

WEB 的一切都离不开 DOM, 否则就不是 WEB, 那是另外的东西, 应该用其它名词.

我们来看看优秀的 jQuery 是怎么做的. jQuery 的链式操作总是把 DOM 对象和你的逻辑代码绑定到一起, 不用讨论具体方法, 方法很多, 不同需求该用哪个就用哪个.

备注: 随着前端的进化, jQuery 的主导作用在下降, 但她的理念和方法依然时尚.

我们知道对象污染是比较敏感的技术, 通常大家都很忌讳, 这是有道理的. 如果一个库污染了 JavaScript 的 Function, Element 对象, 那你要考虑是不是要弃用了, jQuery 的竞争对手曾经因为这个迅速败阵.

但是唯独 DOM 中的元素(具体的 HTML Tag)天生就是要被污染的, 这种例子举不胜举, 即便是铁杆的反对者也不得不用, 因为从 HTML 开始就允许自定义属性, 虽然这不是真正意义的 DOM 污染, 但是不要忘记各大浏览器厂商都在 DOM 中加入了非标准的 property. 所以事实是:

DOM 生下来就被污染了, 从来都不纯洁(标准), 因为这就是我们要的

既然如此, 我们把相关数据以 property 方式合理的命名污染到 DOM 就顺理成章了

这样做甚至连数据管理问题都会方便很多. 如果你不想暴露数据到 DOM 也很好办, 把变换后(非线性的, 最简单取个时间戳加计数器加随机数就好)索引数据污染到 DOM, 真实数据用闭包的方法保护起来就好了.

Map

JavaScript 的 Map 可以接受任意对象作为访问 Key, 甚至 document.body. 虽然前述的几个项目运用了 Map, 但我认为它们用的不够广泛, Map 应该被运用的无处不在.

Map 无障碍的支持任意对象绑定, 这正是动态语言的极致表现

用一门语言就要用她的语言特性, 不然何必开发那么多语言呢?

Dispatcher

分发是使用确定算法的数据分流. 这个很艺术. 必须承认 Redux 的 state 简单, 有效, 通用. 重要的是你可以用她的理念轻松打造自己的 state. 甚至可以说, 无论形式怎么改变, state 的理念是时尚长久的.

设计 Dispatcher 优先考虑 Redux 的 state 的理念

Template

模板在 WEB 非常普遍, 前述几个项目都有涉及. 我们来看看最原生的模板 JavaScript 模板字面量. 我认为 MDN 描述的不够简洁, 更简洁准确的描述是:

JavaScript 模板字面量是字符串求值函数的专用语法形式, 在该模板字符串函数中只能使用求值表达式, 值被转换成字符串类型.

例:

let _ =`
some string ${exp_to_string} other string
`

其中出现的所有东西最终都是字符串

`\n` , `some string `, `exp_to_string`, `other string`, `\n`

显然在 exp_to_string 中可以使用函数, 无论这个函数是传入或者全局的.

那么前述项目中有那个达到了这个水平? 我相信有读者认为有, 我说没有, 因为你忘记了 DOM 对象.

她们支持的是 Vitural-DOM 而非 Real-DOM.

或许你会说, 可以给 HTML Tag 加 id, class 来解决啊, 没错, 但那不是模板技术, 是 HTML 特性, 这种模板不能提供直接访问支持.

所以这些模板技术依然是传统模板技术, 和早期的字符串模板能力相差无几, 无非靠增加指令提升能力而已.

指令多更令人讨厌

这里再次推荐我写的两个模板类工具, 参见 原生的必定美丽, 遵循 Unix 哲学:

  1. Real-DOM 模板引擎 PowJS, 不提供 Dispatcher, 因为这不属于模板要解决的问题
  2. CSS 处理器 PowCSS, 不生成运行时的 StyleSheet, 因为相关工具太多, 请搭配使用

她们生成函数, 函数在 JavaScript 中是 Class first.

你要局部对象, 直接写进去

你要全局对象, 直接写进去

你要变量, 传递就好

你要 Real-DOM, 她就在哪里, 你代码所在的地方正在实时的构建她, 并且可以访问.

如果有开发者做出比 PowJS 更好的 Real-DOM 模板引擎, 我一定会点赞并使用.

Library

开发 Library, 使用 Library, 一口气上五楼.

Framework

我不是 Framework 的反对者, 相反我支持 Framework. 但是我眼中的 Framework 必须具备:

用 Framework 写项目时必须比组合 Library 完成同样工作代码少几倍, 用时少几十倍

不然还是不要自称 Framework 了, 叫 Frame 更贴切, 那里没有 work 只有 torment.

这样的框架也很多, 比如 Bootstrap.

展开阅读全文
加载中

作者的其它热门文章

打赏
2
0 收藏
分享
打赏
0 评论
0 收藏
2
分享
返回顶部
顶部