01|库不再够用的那一刻,前端第一次需要的是“宪法”

上一篇讲到,

jQuery 这类库先统一了浏览器现实。

它们把 DOM、事件、Ajax 这些脏活做顺了,

让前端终于开始像一门能日常干活的工作。

可也正因为它们把活做顺了,

更高层的问题反而会更快冒出来。

因为当 Web 已经越来越像应用时,

前端真正开始难受的,不再只是:

  • 选元素烦不烦
  • 绑事件麻不麻烦
  • 发请求顺不顺手

而会变成:

  • 状态到底放哪里
  • 界面和数据怎么对应
  • 路由怎么管理
  • 多个视图怎么协同
  • 大项目怎么不烂成一锅

也就是说,前端这时候第一次真正大规模需要的,

已经不是更强的工具箱。

而是:

更像“宪法”的结构。

所以 2010 年前后那批框架集中冒出来,

并不是什么巧合。

它们其实都是在回应同一个历史压力:

浏览器已经不像一个脚本补丁场了,它开始像一个需要长期治理的应用现场。


02|Backbone 代表的是一种特别克制的立法:给你结构,但不替你统治太多

这批框架里,Backbone 很有代表性。

因为它很早就把自己的问题意识说得很清楚:

Backbone.js gives structure to web applications

这句话非常值得记。

因为它抓到的已经不是“某个 API 好不好用”。

而是:

应用需要结构。

Backbone 的做法很像一种最小立法。

它给你:

  • Model
  • Collection
  • View
  • Router
  • 事件系统

可它并不想替你把一切都规定死。

你可以把它理解成一种很典型的早期框架气质:

我承认浏览器应用需要更稳的结构,但我不想替你决定太多。

这条路线为什么会有吸引力?

因为在那个阶段,很多开发者已经意识到页面脚本越来越撑不住。

可他们也还没有准备好接受一个太重、太全、太爱替你立规矩的系统。

于是 Backbone 提供了一种特别讨巧的过渡形态:

既承认“应用需要结构”,又尽量保留开发者对结构的主导权。

这也是为什么很多人后来回头看 Backbone

会觉得它不像后来那种“全家桶型框架”。

它更像:

前端第一次承认自己需要架构,但还舍不得交出太多自由。


03|Knockout 则把另一件事推到了前台:界面和状态的关系,最好别再手工硬缝

Backbone 相比,

Knockout 更像是从另一侧切进来的。

它最强的问题意识,不是“整体结构最小够不够”。

而是:

界面和数据之间的关系,能不能别再靠手工同步。

它在首页和文档里特别强调:

  • MVVM pattern
  • declarative bindings
  • dependency tracking
  • automatic UI refresh

这背后真正打中的,是当时浏览器应用最痛的一层现实:

状态变化越来越频繁,而手工维护 DOM 与状态一致性,已经开始越来越不体面了。

这就是 Knockout 很值得写的一点。

因为它让前端世界第一次更明确地感受到:

“绑定”本身也可以成为核心能力。

以前大家更习惯的思路是:

  • 先拿到数据
  • 再自己改 DOM
  • 再自己补事件
  • 再自己维持状态

Knockout 在推动的,是另一种感觉:

让数据模型自己更直接地拖动界面。

你当然可以说,这条线后来也带来了很多问题。

可在当时,它确实精准命中了一个正在爆炸的痛点:

前端越来越不想亲手缝每一次 UI 更新了。


04|Ember 的野心更大:它不只是想给结构,它是想直接给你一整套秩序

如果说 Backbone 像最小立法,

Knockout 像在强化状态和视图的绑定关系,

Ember 代表的就是另一种更强势的路线:

既然浏览器应用已经够复杂,那就别再只给零件了,直接给一整套秩序。

这也是为什么 Ember 这条线特别值得单独看。

因为它是前端框架史里非常典型的一种雄心:

  • 约定优于配置
  • 完整框架
  • 组件、路由、数据流、CLI、发布节奏一起组织

Ember 1.0 Released 那篇公告时,

它甚至已经在公开强调:

the pain ... is now over

这句话特别有戏。

因为它不是在说:

“我们又新增了几个 API。”

它是在说:

前端过去那种混乱而反复变化的架构痛,终于应该结束了。

而且 Ember 后来很快推动出更明确的发布节奏、稳定版本、实验特性入口,

也说明它争的根本不是一个“小而美库”的位置。

它想争的是:

浏览器应用该如何被完整治理。

Ember 这条线后来虽然没有拿到最大市场,

可它的历史作用非常大。

因为它提前把一种后来大家越来越熟悉的框架形态做出来了:

框架不是几个核心 API,而是一整套默认组织方式。


05|AngularJS 为什么当年会这么有吸引力:因为它看起来真的像在替你接管复杂度

很多后来才入行的人,容易低估 AngularJS 当年的冲击力。

因为今天回头看,你很容易先注意到它的历史包袱、脏检查、迁移断裂这些后果。

可如果要写历史,就必须先回到它最有吸引力的时候。

AngularJS 当年强的地方,正在于它给人的感觉是:

你不用再自己一点点拼应用了,框架会替你接手很多以前你得手工扛的复杂度。

它吸引人的点,很集中:

  • 模板驱动
  • 双向绑定
  • 依赖注入
  • 指令系统
  • 完整应用结构

如果你把它放回那个时间点看,

它的诱惑其实非常大。

因为在很多团队眼里,

这几乎像是在说:

前端终于有一套像样的大应用方法论了。

而这也正是 AngularJS 值得写的地方。

它不只是一个流行框架。

它是一种特别强势的历史回答:

既然浏览器应用已经这么复杂,那就别再犹豫了,直接把更多秩序交给框架。

当然,后来的历史也说明,

把太多复杂度压给框架内部机制,会带来新的问题。

可在它崛起的那个瞬间,

这恰恰是它最迷人的地方。

因为它看起来像真的能一次性替团队把混乱收编掉。


06|把这几条线放在一起看,你会发现它们都在争同一件事:谁来解释前端应用的合法形态

BackboneKnockoutEmberAngularJS 表面差很多。

可如果退一步看,会发现它们其实都在抢同一个位置。

它们都在回答:

前端应用到底该长成什么样,才算“合理”。

只是它们各自交出的答案不一样。

Backbone 说:

先给最小结构,别替开发者决定太多。

Knockout 说:

重点是把数据和界面的对应关系做顺。

Ember 说:

别零敲碎打了,直接上完整秩序。

AngularJS 说:

既然复杂度已经失控,那就把更多控制权交给框架。

也就是说,这个阶段最关键的变化不在于:

“框架变多了。”

而在于:

前端第一次开始大规模争论,浏览器应用的合法形态到底应该是什么。

这就是为什么我更愿意把这一阶段叫“抢架构解释权”。

因为这批框架真正竞争的,

已经不是局部能力。

而是:

谁有资格定义应用结构的默认答案。


07|可它们最后都没有彻底坐稳天下,因为它们仍然在回答旧问题

这批框架的历史意义很大,

但它们也并没有彻底终结战争。

原因不难理解。

因为它们虽然都在认真回答“浏览器应用怎么组织”,

可它们大多还是站在一种旧一点的 UI 直觉上:

  • 模板很重要
  • 视图层和数据层要靠绑定或控制器协调
  • 应用结构更像传统 MVC / MVVM 的前端变体

这条线当然在当时有很强合理性。

但随着前端继续变重,

另一个更激进的问题会慢慢浮出来:

如果 UI 本身可以直接被理解成状态的投影,那我们是不是根本不需要再沿着模板、控制器、双向绑定那套心智继续走下去?

这就是下一轮大改道的入口。

也就是 React 这条线真正要切进来的位置。

它不是简单再做一个框架。

它会从更底层改写问题:

别再问“模板和控制器怎么配合”,改问“状态如何渲染成界面”。


08|很多今天的框架常识,其实都是那一轮立下的规矩

为什么这一段前史今天还值得认真写?

因为很多现代前端里最习以为常的东西,

其实就是在这场 MVC / MVVM 爆发期先被推成常识的。

比如:

  • 前端应用应该有路由
  • 前端应用应该有组件或视图层边界
  • 前端应用应该有状态与界面的系统性关系
  • 前端项目应该有统一的组织方式

这些今天看起来像常识,

可在当时其实都是打出来的。

而且直到今天,

我们依然还在反复回答同样的问题:

  • 框架到底该管多宽
  • 该给开发者多少自由
  • 该靠模板、运行时还是编译器
  • 状态和视图之间到底该怎样耦合

所以这段历史真正值得记住的,不是:

“曾经有很多老框架。”

而是:

当前端第一次发现自己需要的不只是库,而是一整套浏览器应用宪法时,所有人都在抢着解释:一个前端应用到底该怎样才算合法。

下一篇要讲的,就是这场争夺里的最大改道者:

为什么 React 最后赢下的,不只是一个框架位置,而是整套 UI 的思考方式。


参考与延伸阅读

  1. Backbone.js
    https://backbonejs.org/

  2. Backbone Annotated Source
    https://backbonejs.org/docs/backbone.html

  3. Knockout : Introduction
    https://knockoutjs.com/documentation/introduction.html

  4. Knockout : Home
    https://knockoutjs.com/

  5. Ember 1.0 Released
    https://blog.emberjs.com/ember-1-0-released/

  6. The Post-1.0 Release Cycle
    https://emberjs.com/blog/2013/09/06/new-ember-release-process.html

  7. Ember Guides: Core Concepts
    https://guides.emberjs.com/release/getting-started/core-concepts/

  8. Defining Your Routes - Ember Guides
    https://guides.emberjs.com/release/routing/defining-your-routes

  9. AngularJS Guide: Directives
    https://docs.angularjs.org/guide/directive

  10. AngularJS Guide: Dependency Injection
    https://docs.angularjs.org/guide/di

  11. AngularJS Guide: Controllers
    https://docs.angularjs.org/guide/controller

  12. Thank you, Angular
    https://blog.angular.dev/thank-you-angular-d90d70f2e9d8

  13. Finding a Path Forward with AngularJS
    https://blog.angular.dev/finding-a-path-forward-with-angularjs-7e186fdd4429