
> 你真的需要 React、Vue、Bootstrap 吗?本文分享如何用纯 HTML + CSS + JavaScript 开发企业级管理后台,零 npm、零 CDN、零 node_modules。
2026 年了,前端框架已经卷到飞起。但回过头想想:
我选择了一条"极端"路线:完全零外部依赖。所有代码自己写,一切责任自负。
ES Modules 已经全面支持,不需要 Webpack/Vite:
<p>import { createApp, ref, reactive } from './js/core.js';</p>
<p>import { Button, Table, Modal } from './js/components.js';</p>
<p>import { fetchApi, formatDate } from './js/utils.js';</p>
<p>// 开始写业务逻辑</p>自己实现一个超轻量的响应式系统:
// js/core.js — 仅 50 行
let currentEffect = null;
const depsMap = new WeakMap();
export function ref(value) {
const dep = new Set();
return {
get value() {
if (currentEffect) { depsMap.set(currentEffect, dep); dep.add(currentEffect); }
return value;
},
set value(newVal) {
if (value !== newVal) { value = newVal; dep.forEach(fn => fn()); }
}
};
}
export function watchEffect(fn) {
currentEffect = fn; fn(); currentEffect = null;
}不需要 JSX,不需要 template 编译器:
// js/components.js
export function DataTable({ columns, data, onRowClick }) {
const el = document.createElement('table');
el.className = 'data-table';
// 表头
const thead = document.createElement('thead');
thead.innerHTML = ${columns.map(c => ${c.label}).join('')};
el.appendChild(thead);
// 表体
const tbody = document.createElement('tbody');
tbody.innerHTML = data.map(row =>
${columns.map(c => ${row[c.key] ?? ''}).join('')}
).join('');
tbody.querySelectorAll('tr').forEach((tr, i) => {
tr.addEventListener('click', () => onRowClick?.(data[i]));
});
el.appendChild(tbody);
return el;
}单页应用路由不需要 react-router 那套重装备:
// js/router.js
const routes = new Map();
export function route(path, handler) {
routes.set(path, handler);
}
export function navigate(path) {
window.location.hash = path;
}
window.addEventListener('hashchange', () => {
const path = window.location.hash.slice(1) || '/';
const handler = routes.get(path);
if (handler) {
document.getElementById('app').innerHTML = '';
document.getElementById('app').appendChild(handler());
}
});// js/store.js
export function createStore(initialState) {
let state = { ...initialState };
const listeners = new Set();
return {
getState: () => ({ ...state }),
setState: (partial) => {
state = { ...state, ...partial };
listeners.forEach(fn => fn(state));
},
subscribe: (fn) => { listeners.add(fn); return () => listeners.delete(fn); }
};
}不需要 Tailwind 那些预处理:
:root {
--color-primary: #0052d9;
--color-bg: #f5f5f5;
--color-text: #333;
--radius: 8px;
--shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.card {
background: #fff;
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 20px;
}
.card__title {
font-size: 18px;
font-weight: 600;
color: var(--color-text);
}
.btn--primary {
background: var(--color-primary);
color: #fff;
border: none;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
}// js/api.js
const BASE_URL = 'https://api.rmzdb.cloud';
export async function apiGet(path, params = {}) {
const qs = new URLSearchParams(params).toString();
const res = await fetch(${BASE_URL}${path}?${qs}, {
headers: { 'Authorization': 'Bearer ' + getToken() }
});
if (!res.ok) throw new Error(API Error: ${res.status});
return res.json();
}
export async function apiPost(path, body) {
const res = await fetch(${BASE_URL}${path}, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + getToken()
},
body: JSON.stringify(body)
});
if (!res.ok) throw new Error(API Error: ${res.status});
return res.json();
}以下是我用这套方案搭建的实际项目结构:
admin-frontend/
├── index.html # 入口
├── css/
│ └── style.css # 全局样式 + CSS变量
├── js/
│ ├── core.js # 响应式引擎 (50行)
│ ├── router.js # 路由 (30行)
│ ├── store.js # 状态管理 (25行)
│ ├── api.js # HTTP封装 (40行)
│ ├── components.js # 组件库 (300行)
│ └── utils.js # 工具函数
├── pages/
│ ├── dashboard.js # 仪表盘
│ ├── users.js # 用户管理
│ └── settings.js # 系统设置
└── favicon.svg总代码量不到 1000 行,gzip 后不到 5KB。
| 指标 | React + Ant Design | 纯原生方案 |
|------|:---:|:---:|
| node_modules | 200MB+ | 0 |
| 首屏加载 | 1.2s | 0.2s |
| gzip 后大小 | ~80KB | ~5KB |
| 构建时间 | 30s | 0 |
| 外部依赖 | 500+ | 0 |
零依赖不是银弹。以下场景还是老老实实用框架:
零依赖的核心思想不是"反对框架",而是对每一行引入的代码负责。
当你自己写了路由、状态管理、组件系统,你会比用任何框架都更理解你的代码。而且——你的页面永远不会因为 CDN 挂了而白屏,永远不会因为依赖升级而改业务代码。
这就是数据主权的意义。
---
你的项目里有多少个 node_modules?欢迎评论区晒一下。
本文为作者原创,未经授权禁止转载、洗稿、搬运。如需引用请保留原文链接。