🔗 关系图谱 · 技术因果链
这张图在说什么
前端三十年不是一堆孤立技术的罗列,而是一条因果链:几乎每一项技术,都是为了解决上一项的副作用而诞生的。 这张图用箭头 + 边标签,把”谁催生了谁、为什么催生”画出来。读它的正确姿势不是看节点,而是顺着箭头读边上的标签——那才是历史的真正动力。
怎么看
- 节点 = 一项技术 / 一个范式
- 箭头方向 = 时间与因果方向(A 催生 B)
- 边标签 = 为什么(A 的什么痛点 / 什么红利,导致了 B)
- subgraph 分组 = 时代。横向看一层抽象的演进,纵向看时代的更替。
一、总因果图
flowchart TD %% ===== 浏览器时代 ===== subgraph ERA1["🌐 浏览器时代 1995-2005"] js["JavaScript 1995"] css["CSS / DOM"] browserwar["浏览器战争<br/>NN vs IE"] xhr["XMLHttpRequest 1999"] js --> css browserwar -->|"各家私有 API 互不兼容"| compat["兼容性地狱"] browserwar -->|"IE 内置非标准对象"| xhr end %% ===== Ajax 时代 ===== subgraph ERA2["📡 Ajax 时代 2005-2013"] ajax["Ajax 2005 命名"] jquery["jQuery 2006"] v8["V8 引擎 2008"] node["Node.js 2009"] backbone["Backbone 2010"] angularjs["AngularJS 2010"] xhr -->|"异步局部刷新成为可能"| ajax ajax -->|"Gmail/Google Maps 证明网页能做应用"| webapp["网页变成应用"] compat -->|"抹平浏览器差异的迫切需求"| jquery ajax -->|"需要顺手的 DOM + Ajax 封装"| jquery webapp --> jquery end %% ===== SPA 时代 ===== subgraph ERA3["⚛️ SPA 时代 2013-2018"] react["React 2013"] vue["Vue 2014"] angular2["Angular 2+ 2016"] vdom["虚拟 DOM"] oneway["单向数据流"] spa["SPA 单页应用"] redux["Redux 2015"] es6["ES6 2015"] jquery -->|"命令式 DOM 不可维护 / 无组件复用"| react angularjs -->|"双向绑定+脏检查在大应用性能崩溃"| react angularjs -->|"概念太重, 想要渐进式"| vue angularjs -->|"推倒重来, 拥抱 TS"| angular2 react --> vdom react --> oneway vdom -->|"声明式渲染在性能上变得可行"| spa oneway --> spa react --> spa oneway -->|"跨组件共享状态难"| redux es6 -->|"class/箭头/模块, 语言现代化"| react end %% ===== 工程化时代 ===== subgraph ERA4["🔧 工程化时代 2018-2023"] ssr["SSR / SSG / ISR / RSC"] webpack["Webpack 2014→"] vite["Vite 2020"] esm["ES Modules"] babel["Babel"] ts["TypeScript 2012"] hooks["React Hooks 2019"] zustand["Zustand 2021"] svelte["Svelte 编译时"] pnpm["pnpm 2017"] spa -->|"首屏白屏 + SEO 灾难"| ssr spa -->|"组件化工程需要模块打包"| webpack webpack -->|"冷启动 / HMR 太慢"| vite esm -->|"浏览器原生支持模块, 开发期免打包"| vite babel -->|"让 JSX/ES6 跑在老浏览器"| react ts -->|"大型应用需要类型约束"| angular2 react -->|"class 组件逻辑复用难 (HOC/render props 地狱)"| hooks redux -->|"样板代码太多, 想要极简"| zustand vdom -->|"反思: 虚拟 DOM 有运行时开销"| svelte npmyarn["npm → Yarn"] -->|"node_modules 黑洞 + 幽灵依赖"| pnpm end %% ===== 模块化主线(贯穿) ===== subgraph MOD["📦 模块化主线"] scripttag["script 标签全局污染"] commonjs["CommonJS / AMD"] browserify["Browserify 2011"] scripttag -->|"全局变量冲突, 无依赖管理"| commonjs commonjs -->|"Node 的模块能否搬到浏览器?"| browserify browserify -->|"打包思路被发扬光大"| webpack commonjs -->|"标准缺位, 社区先行"| esm end %% ===== 运行时主线 ===== v8 -->|"JS 终于足够快"| node node -->|"JS 能跑在服务端 → 前端工程化基础设施"| webpack node -->|"npm 生态爆发"| npmyarn node -->|"历史包袱: 安全/TS/模块"| deno["Deno 2020"] node -->|"想要更快的一体化运行时"| bun["Bun 2022"] ts --> deno %% ===== AI 时代 ===== subgraph ERA5["🤖 AI 时代 2023-未来"] copilot["GitHub Copilot 2021"] cursor["Cursor 2023"] claudecode["Claude Code 2024"] agent["Agent"] mcp["MCP 2024"] ainative["AI-Native 开发"] copilot -->|"补全不够, 想要理解整个项目"| cursor cursor -->|"从 IDE 内补全到自主执行"| claudecode claudecode -->|"能用工具/多步规划"| agent agent -->|"需要标准化的工具/上下文协议"| mcp mcp --> ainative agent --> ainative end %% ===== 汇入 AI ===== ts -->|"类型即给 AI 的规格说明"| copilot react -->|"海量训练语料, 成为 AI 默认输出"| copilot vite -->|"快反馈闭环利于 AI 迭代"| ainative ssr -->|"渲染范式继续演化"| ainative svelte -->|"编译时思路延续"| ainative %% ===== 样式 ===== classDef era1 fill:#e3f2fd,stroke:#1976d2; classDef era5 fill:#f3e5f5,stroke:#7b1fa2; class js,css,browserwar,xhr,compat era1; class copilot,cursor,claudecode,agent,mcp,ainative era5;
二、读图:四条主脉络
这张网看似复杂,其实只有四条主线在反复交织。把它们单独抽出来,因果就清晰了。
脉络 1:抽象上移线(整张图的脊柱)
手写 DOM → jQuery(命令式封装) → React/Vue(声明式框架) → Svelte(编译器) → AI Coding(自然语言)
每一代都在做同一件事:让开发者少关心一层底层细节。
- jQuery:你还要关心”怎么操作 DOM”,但不用关心浏览器差异。
- React:你连”怎么操作 DOM”都不用管了,只描述
UI = f(state)。 - Svelte:你连”运行时框架”都不用打包了,编译器在构建期把它干掉。
- AI:你连”怎么写代码”都可以用自然语言描述,模型补全实现。
抽象每上移一层,生产力提升一个量级,但理解力也下沉一层(见 演进逻辑-五个永恒矛盾 的矛盾五)。
脉络 2:模块化线(从混乱到标准的潮汐)
script 标签(全局污染) → CommonJS/AMD(社区方案) → Browserify(把 Node 模块搬进浏览器)
→ Webpack(万物皆模块) → (慢) → Vite ← ESM(标准最终追认)
这是一条典型的”社区先行、标准追认”潮汐:浏览器迟迟没有原生模块,社区造了 CommonJS/AMD/UMD 一堆方言;Browserify/Webpack 用打包把方言抹平;最后 ESM 成为语言标准,Vite 借浏览器原生 ESM 实现”开发期免打包”,反过来淘汰了打包器的一部分存在理由。
脉络 3:渲染螺旋线(否定之否定)
MPA 服务端渲染 → (交互弱) → SPA 客户端渲染 → (白屏/SEO) → SSR 回归
→ SSG(预渲染) → ISR(增量) → RSC(服务端组件)
渲染模式不是直线进步,而是螺旋:前端把渲染从服务端搬到客户端(SPA),解决了交互问题却制造了白屏和 SEO;于是又把渲染搬回服务端(SSR/RSC),但这次带着组件化和水合(hydration)的新能力回去。详见 渲染模式演进史。
脉络 4:性能/DX 线(工具链的军备竞赛)
Webpack(功能全但慢) → esbuild/SWC(Go/Rust 重写) → Vite(原生 ESM + 按需编译)
npm(慢/黑洞) → Yarn(锁文件/并行) → pnpm(硬链接/解决幽灵依赖)
Node → Deno/Bun(更快的一体化运行时)
当框架格局稳定后,竞争焦点转向开发体验(DX)与构建速度。“用更快的语言(Go/Rust)重写 JS 工具链”成为 2020 年后的主旋律。详见 前端工程化演进史、为什么Vite能取代Webpack。
一句话总结这张图
没有一项技术是凭空出现的——每一代都是上一代副作用的解药,而每一剂解药又埋下下一代的病根。 这就是前端演化的第一性逻辑。
🔗 相关:MOC-前端技术演化史 | 时间线总览 | 演进逻辑-五个永恒矛盾 | 术语表 🔗 时代:1995-2005 浏览器时代 | 2005-2013 Ajax时代 | 2013-2018 SPA时代 | 2018-2023 工程化时代 | 2023-未来 AI时代 🔗 关键技术:jQuery | React | Vite | Webpack | Node.js | Svelte | Agent与MCP