前端十年风云录:那些年我们追过的框架
十年前,前端开发还停留在 jQuery 和 Backbone.js 的时代,如今却已演变为 React、Vue、Angular 三足鼎立的格局。框架的迭代速度令人眼花缭乱,开发者们一边追逐新技术,一边怀念那些逐渐淡出视野的“老朋友”。
jQuery:从王者到“遗产代码”
2006 年诞生的 jQuery 用 $()
统一了浏览器 API 的碎片化问题。当年一个简单的 AJAX 请求可以写成:
$.ajax({
url: '/api/data',
success: function(data) {
$('#result').html(data);
},
error: function() {
alert('Error loading data');
}
});
其链式调用语法风靡一时:
$('.menu-item')
.addClass('active')
.siblings()
.removeClass('active');
但随着虚拟 DOM 技术的兴起,直接操作 DOM 的方式逐渐被淘汰。如今 jQuery 多出现在老旧项目中,成为开发者口中的“遗产代码”。
AngularJS:双向绑定的革命者
2010 年 Google 推出的 AngularJS 带来了颠覆性的变化。其双向数据绑定让开发者眼前一亮:
<div ng-app="myApp" ng-controller="myCtrl">
<input ng-model="name">
<h1>Hello {{name}}!</h1>
</div>
<script>
angular.module('myApp', [])
.controller('myCtrl', function($scope) {
$scope.name = 'World';
});
</script>
脏检查机制虽然强大,但在大型应用中性能问题逐渐暴露。2016 年 Angular 2+ 的彻底重写让许多开发者转向其他框架。
React:虚拟 DOM 的胜利
2013 年 Facebook 开源的 React 带来了全新的开发范式。这个简单的计数器组件展示了其核心思想:
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
虚拟 DOM 的 diff 算法极大提升了性能,JSX 语法则模糊了 HTML 和 JavaScript 的边界。React Hooks 的推出更是彻底改变了组件编写方式。
Vue:渐进式的优雅方案
2014 年尤雨溪发布的 Vue.js 以其渐进式特性获得青睐。单文件组件(SFC)将模板、逻辑和样式完美结合:
<template>
<div>
<button @click="count++">Count is: {{ count }}</button>
</div>
</template>
<script>
export default {
data() {
return { count: 0 }
}
}
</script>
<style scoped>
button { color: #42b983; }
</style>
从 2.x 的 Options API 到 3.x 的 Composition API,Vue 始终保持着低学习曲线的优势。
现代前端框架的三国杀
当下主流框架各具特色:
-
React 18 引入并发渲染:
import { startTransition } from 'react'; startTransition(() => { setState(newState); });
-
Vue 3 的
<script setup>
语法:<script setup> const msg = 'Hello World!'; </script>
-
Angular 15 的独立组件:
@Component({ standalone: true, template: `...` }) export class MyStandaloneComponent {}
被遗忘的挑战者们
许多框架曾昙花一现:
-
Backbone.js 的 MVC 实现:
const Todo = Backbone.Model.extend({ defaults: { title: '', completed: false } });
-
Ember.js 的约定优于配置:
Ember.Route.extend({ model() { return this.store.findAll('post'); } });
-
Knockout.js 的 MVVM 模式:
<p>First name: <input data-bind="value: firstName" /></p>
编译时框架的崛起
新一代框架开始移部分逻辑到编译阶段:
-
Svelte 的零运行时:
<script> let count = 0; </script> <button on:click={() => count++}> Clicked {count} times </button>
-
SolidJS 的响应式原理:
function Counter() { const [count, setCount] = createSignal(0); return <button onClick={() => setCount(count() + 1)}>{count()}</button>; }
全栈框架的野心
框架开始向后端延伸:
-
Next.js 的混合渲染:
export async function getServerSideProps() { const res = await fetch('https://api.example.com/data'); return { props: { data: await res.json() } }; }
-
Nuxt 3 的自动导入:
<script setup> // 自动导入的 useFetch const { data } = await useFetch('/api/hello'); </script>
微前端与模块联邦
大型应用架构方案兴起:
// 模块联邦配置示例
new ModuleFederationPlugin({
name: 'app1',
exposes: { './Button': './src/Button' },
remotes: { app2: 'app2@http://localhost:3002/remoteEntry.js' }
});
工具链的军备竞赛
现代前端开发离不开这些工具:
-
Vite 的闪电冷启动:
npm create vite@latest my-project --template react
-
Turbopack 的增量编译:
// next.config.js experimental: { turbopack: true }
类型系统的全面渗透
TypeScript 已成为行业标准:
interface User {
id: number;
name: string;
}
const getUser = async (id: number): Promise<User> => {
const res = await fetch(`/api/users/${id}`);
return res.json();
};
CSS 的范式转移
从 CSS-in-JS 到实用类优先:
// styled-components
const Button = styled.button`
background: ${props => props.primary ? '#4CAF50' : 'white'};
`;
// Tailwind
<button className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
Button
</button>
状态管理的永恒命题
从 Flux 到现代方案:
// Redux Toolkit
const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: state => state + 1
}
});
// Zustand
const useStore = create(set => ({
bears: 0,
increase: () => set(state => ({ bears: state.bears + 1 }))
}));
移动端的跨界方案
React Native 依然活跃:
import { Text, View } from 'react-native';
function HelloWorldApp() {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Hello, world!</Text>
</View>
);
}
WebAssembly 的新边疆
前端性能的突破:
// Rust 编译为 wasm
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
低代码平台的冲击
// 某些平台生成的代码结构
export default {
"components": [
{
"type": "Button",
"props": { "text": "Submit" }
}
]
}
开发者体验的持续优化
现代工具链带来的改变:
# 现代项目初始化对比
npm init vite@latest # 2020s
vs
npm install -g create-react-app # 2010s
浏览器 API 的进化
原生能力不断增强:
// 文件系统访问 API
const fileHandle = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
前端测试的成熟
测试方案日趋完善:
// Testing Library 示例
test('loads and displays greeting', async () => {
render(<Fetch url="/greeting" />);
await screen.findByRole('heading');
expect(screen.getByRole('heading')).toHaveTextContent('hello there');
});
构建工具的范式转移
从配置化到约定式:
// vite.config.js
export default defineConfig({
plugins: [react()]
});
// 对比 webpack.config.js
module.exports = {
module: { rules: [/*...*/] }
};
前端工程化的极致
Monorepo 成为标配:
// turbo.json
{
"pipeline": {
"build": { "dependsOn": ["^build"] }
}
}
设计系统的崛起
// 现代组件库用法
<Button
variant="primary"
size="lg"
leftIcon={<EmailIcon />}
>
Contact
</Button>
前端性能的永恒追求
优化手段不断升级:
// 图片懒加载
<img loading="lazy" src="image.jpg" alt="...">
// 新的性能API
const { timing } = await performance.measureUserAgentSpecificMemory();
可访问性的觉醒
<button aria-label="Close menu" onclick="close()">
<svg><!-- close icon --></svg>
</button>
前端安全的新挑战
// CSP 策略
Content-Security-Policy: script-src 'self' https://apis.example.com
开发者生态的繁荣
# 现代前端项目的依赖数量
npm ls | wc -l # 通常超过 1000
前端职业的变迁
从切图仔到架构师,技术栈要求不断拓宽:
2008年要求:
- HTML/CSS
- jQuery
- Photoshop
2023年要求:
- React/Vue
- TypeScript
- Webpack/Vite
- Node.js 基础
- 性能优化
- 测试驱动开发
框架未来的可能性
// 服务端组件示例 (React)
async function UserList() {
const users = await db.users.findMany();
return users.map(user => <div key={user.id}>{user.name}</div>);
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn