前言 :前后端分离是当代 Web 开发的主流架构,模块化是代码可维护性的基石,而一份好的 prompt 则是与 AI 协作的核心竞争力。本文以一个极简的
user-chat项目为例,从前端三件套到后端 json-server,从 HTML 语义化标签到 Bootstrap CSS 框架,带你走一遍"手工搭建全栈项目"的完整链路。
目录
- 项目全景:前后端分离
- [前端三件套:HTML + CSS + JS](#前端三件套:HTML + CSS + JS "#%E5%89%8D%E7%AB%AF%E4%B8%89%E4%BB%B6%E5%A5%97html--css--js")
- 模块化设计思想
- [HTML 语义化与搜索引擎友好](#HTML 语义化与搜索引擎友好 "#html-%E8%AF%AD%E4%B9%89%E5%8C%96%E4%B8%8E%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E5%8F%8B%E5%A5%BD")
- [盒子模型与 DOM 编程](#盒子模型与 DOM 编程 "#%E7%9B%92%E5%AD%90%E6%A8%A1%E5%9E%8B%E4%B8%8E-dom-%E7%BC%96%E7%A8%8B")
- [Bootstrap CSS 框架:让页面好看](#Bootstrap CSS 框架:让页面好看 "#bootstrap-css-%E6%A1%86%E6%9E%B6%E8%AE%A9%E9%A1%B5%E9%9D%A2%E5%A5%BD%E7%9C%8B")
- [后端准备:json-server 快速搭建 API](#后端准备:json-server 快速搭建 API "#%E5%90%8E%E7%AB%AF%E5%87%86%E5%A4%87json-server-%E5%BF%AB%E9%80%9F%E6%90%AD%E5%BB%BA-api")
- [Prompt 思考:AI 时代的高效协作](#Prompt 思考:AI 时代的高效协作 "#prompt-%E6%80%9D%E8%80%83ai-%E6%97%B6%E4%BB%A3%E7%9A%84%E9%AB%98%E6%95%88%E5%8D%8F%E4%BD%9C")
- 总结
项目全景:前后端分离
目录结构
bash
user-chat/
├── fe/ # 前端:专注 UI 与交互
│ ├── index.html # 结构 + 样式引入
│ └── common.js # DOM 编程 + 数据渲染
├── backend/ # 后端:专注数据与 API
│ ├── db.json # 数据库(JSON 文件)
│ ├── package.json # 后端项目描述
│ └── node_modules/ # 依赖(json-server 等)
└── readme.md # 项目文档
为什么要前后端分离?
HTML + CSS + JS"] -->|"HTTP 请求"| B["后端 API Server
json-server"] B -->|"JSON 数据"| A
| 维度 | 传统混写 | 前后端分离 |
|---|---|---|
| 职责 | 后端模板渲染 HTML | 前端管页面,后端管数据 |
| 开发 | 前后端互相等待 | 前后端并行开发 |
| 复用 | 服务端代码难跨项目 | API 可同时服务 Web / App / 小程序 |
| 维护 | 逻辑耦合在一起 | 定位 bug 清晰:前端 or 后端 |
在这个项目中,fe/ 目录和 backend/ 目录就是两个完全独立的"关注域":
- 前端只看得到 HTML 页面,它不关心数据从哪里来------直接写死的数组也好,fetch 请求的 JSON 也好,对 DOM 渲染来说没有区别。
- 后端只管提供数据 ,
json-server db.json一行命令就把 JSON 文件变成了 RESTful API,前端可以用fetch('/users')来消费。
在实际的 OPC(One Person Company)模式下,一个人同时写前端和后端,分离架构让换脑成本降到最低------上午调 UI、下午调 API,互不干扰。
前端三件套:HTML + CSS + JS
代码骨架
fe/index.html 展示了一个标准 HTML5 页面的"三件套"组织方式:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- CSS 在头部引入:让样式更早加载,用户更快看到好看的页面 -->
<link href="bootstrap.css" rel="stylesheet">
</head>
<body>
<!-- HTML 负责结构 -->
<!-- JS 在底部引入:等 DOM 树建好再执行 -->
<script src="./common.js"></script>
</body>
</html>
三件套各自职责
| 技术 | 负责 | 在本项目中的体现 |
|---|---|---|
| HTML | 结构------页面有什么 | header、main、table、footer |
| CSS | 样式------页面长什么样 | Bootstrap CDN + 行内思考(container、row、col) |
| JS | 行为------页面能干什么 | DOM 查询、动态插入 <tr> |
骨架"] --> B["CSS
皮肤"] A --> C["JS
肌肉"] B --> D["用户看到的完整页面"] C --> D
一个小细节:CSS 放在
<head>中、JS 放在</body>前。这是为了让样式尽早生效,用户打开页面的第一眼就是"美的",而 JS 不阻塞 DOM 树的构建。
模块化设计思想
什么是模块化?
模块化就是把代码按职责拆到不同的文件和目录,每个文件只做一件事。
包含所有逻辑"] end subgraph 模块化 Y1["fe/ 目录:前端专属"] Y2["backend/ 目录:后端专属"] Y3["common.js:DOM 渲染"] Y4["db.json:数据存储"] end X -->|"重构"| Y1 X -->|"重构"| Y2
为什么需要模块化?
| 问题 | 无模块化 | 有模块化 |
|---|---|---|
| 维护 | 改一个功能要翻几千行代码 | 定位到具体文件,直接改 |
| 扩展 | 加新功能怕动到旧逻辑 | 新功能 = 新文件,互不影响 |
| 优化 | 牵一发动全身 | 按需优化单个模块 |
| 协作 | 多人同时改一个文件 = 冲突地狱 | 各改各的目录,并行推进 |
本项目的模块划分
go
fe/ → "我只管用户看到的东西"
index.html → "我只管结构骨架"
common.js → "我只管 DOM 操作和数据渲染"
backend/ → "我只管数据服务"
db.json → "我只管存数据"
package.json → "我只管描述这个 Node 项目"
每个目录有明确的职责边界,每个文件只做一件事。这就是模块化的核心------把复杂问题拆成简单问题,再逐个击破。
HTML 语义化与搜索引擎友好
不要 <div> 满天飞
HTML5 提供了丰富的语义化标签,每个标签自带"含义",让搜索引擎和辅助设备(如屏幕阅读器)能理解页面结构。
html
<!-- ❌ 纯 div 堆砌:机器看不懂结构 -->
<div class="header">标题</div>
<div class="main">
<div class="sidebar">侧栏</div>
<div class="content">
<div class="table">...</div>
</div>
</div>
<div class="footer">底部</div>
<!-- ✅ 语义化标签:机器和人一眼看懂 -->
<header>标题</header>
<main>
<aside>侧栏</aside>
<table>
<thead>...</thead>
<tbody>...</tbody>
</table>
</main>
<footer>底部</footer>
本项目使用的语义化标签
| 标签 | 语义 | 本项目位置 |
|---|---|---|
<header> |
页头 / 导航区域 | index.html:10 |
<main> |
页面主体内容(一个页面仅一个) | index.html:12 |
<aside> |
侧边栏 / 补充内容 | index.html:13 |
<footer> |
页脚 / 版权信息 | index.html:35 |
<table> + <thead> + <tbody> |
数据表格 | index.html:15-31 |
语义化 = SEO 友好
搜索引擎的爬虫在解析页面时,会利用语义标签来理解内容权重:
爬虫认为:核心内容"] --> B["加分"] C["\
爬虫认为:一个普通容器"] --> D["不加分"]
<main>直接告诉爬虫"这是正文",<div class="main">需要爬虫"猜"。<table>+<thead>+<tbody>让爬虫识别出这是结构化数据,而非布局用的表格。<header>/<footer>帮助爬虫分清哪些是导航、哪些是脚注,不被噪音干扰。
通俗理解:你可以把语义标签想象成马路上画的箭头线和标识------不是你自己看的,而是让别人(搜索引擎)更容易读懂你的页面。
盒子模型与 DOM 编程
盒子模型
HTML 里默认有两类标签:
| 类型 | 默认行为 | 典型标签 | 比喻 |
|---|---|---|---|
| 块级元素 | 独占一行,可设宽高 | <div> <header> <main> <p> <table> |
做盒子------搭骨架 |
| 行内元素 | 不换行,宽高由内容撑开 | <span> <a> <img> <strong> |
装内容------填血肉 |
开发口诀:先写盒子,再写内容。
css
/* Bootstrap 提供的 container 就是典型的"盒子"思路 */
.container {
/* 中间内容宽度固定,左右留白 */
max-width: 1170px;
margin-left: auto;
margin-right: auto;
}
container"] --> B["盒子(块级)
row"] B --> C["盒子(块级)
col"] C --> D["内容
table / 文字 / 图片"]
CSS 布局的三板斧
| 概念 | 作用 | 本项目示例 |
|---|---|---|
| container | 固定宽度 + 居中,适配不同屏幕 | <main class="container"> |
| row | 一行,容纳列 | <div class="row"> |
| col | 列,放在 row 里 | <div class="col-md-6"> |
这套"容器 → 行 → 列"的布局模式从 PC 时代延续至今,解决了不同尺寸设备上内容对齐的经典问题。
DOM 编程
**DOM(Document Object Model)**是浏览器把 HTML 文本解析成 JS 可以操作的对象树。
(根节点)"] --> B["document.documentElement
\"] B --> C["document.head
\"] B --> D["document.body
\"] D --> E["header"] D --> F["main"] D --> G["footer"] F --> H["aside"] F --> I["div.row"] I --> J["table"] J --> K["thead"] J --> L["tbody"]
再看 common.js 里的 DOM 操作:
js
// 1. 通过 CSS 选择器"穿越"DOM 树,定位到目标节点
const oBody = document.querySelector('.table tbody');
// 2. 数据驱动------遍历数组,动态生成 HTML 片段
for (let user of users) {
oBody.innerHTML += `
<tr>
<td>${i}</td>
<td>${user.name}</td>
<td>${user.nickname}</td>
<td>${user.hometown}</td>
</tr>
`;
}
核心三步:
- 查节点 ---
document.querySelector()从 HTML 页面"走进"JS 内存 - 改内容 ---
.innerHTML动态修改 DOM 节点的内部 HTML - 数据驱动 --- 遍历 JS 数组,模板字符串拼出 HTML,渲染到页面
面试常考的"不用框架,手写一个数据渲染"就是这个思路。大厂特别注重这种底层能力------不依赖 React/Vue,用原生 JS 完成 DOM 操作。
Bootstrap CSS 框架:让页面好看
为什么聊 Bootstrap?
白底黑字,无布局"] -->|"引入 Bootstrap"| B["Bootstrap 加持
栅格、表格样式、响应式"]
原生 HTML 像素颜,结构是对的但不好看。Bootstrap 是一套开箱即用的 CSS 样式库,Twitter 团队出品,解决的就是"后端程序员不会写 CSS"的痛点。
本项目如何引入
html
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
一行 CDN 链接,不需要 npm install,不需要构建工具,加载即用。
本项目使用的 Bootstrap 特性
| class | 作用 | 效果 |
|---|---|---|
container |
固定宽度容器,居中 | 内容不会撑满全屏,左右有留白 |
row |
弹性行 | 内部的 col 按 12 列栅格排布 |
col-md-6 |
占 6/12 = 一半宽度 | 中等屏幕以上占半行 |
col-md-offset-3 |
向右偏移 3/12 | 让表格居中显示 |
table |
Bootstrap 表格基础样式 | 带边框、间距的表格 |
table-striped |
斑马条纹 | 奇数行和偶数行颜色交替 |
Bootstrap 的核心设计:12 列栅格系统
(50% 宽度)"] B --> D["col-md-4 = 占 4 份
(33% 宽度)"] B --> E["col-md-3 = 占 3 份
(25% 宽度)"]
这套栅格系统让布局从"靠感觉微调"变成了"靠数字精确控制"------col-md-6 col-md-offset-3 翻译成人话就是"占半行,左右各空四分之一",无论屏幕多大都能保持居中。
后端准备:json-server 快速搭建 API
从零到 API 只需两步
bash
# Step 1:初始化 Node 项目
npm init -y
# 生成 package.json ------ 后端项目的"身份证"
# Step 2:安装 json-server
npm i json-server
# 一个把 JSON 文件变成 RESTful API 的神器
package.json------后端项目的描述文件
json
{
"name": "backend",
"version": "1.0.0",
"scripts": {
"dev": "json-server db.json"
},
"dependencies": {
"json-server": "^1.0.0-beta.15"
}
}
scripts.dev:定义了启动命令,npm run dev一行启动整个后端。dependencies:声明了项目依赖哪些第三方包,其他开发者 clone 代码后npm install即可还原环境。
db.json------以文件为数据库
json
{
"users": [
{ "id": 1, "name": "李宇刚", "hometown": "南昌", "nickname": "东理薛之谦" },
{ "id": 2, "name": "胡航", "hometown": "南昌", "nickname": "航哥" },
{ "id": 3, "name": "赖庆庆", "hometown": "信丰", "nickname": "橙帅" }
]
}
一行 npm run dev 后,json-server 自动生成以下 API:
| HTTP 方法 | 端点 | 说明 |
|---|---|---|
GET |
/users |
获取所有用户 |
GET |
/users/1 |
获取 id=1 的用户 |
POST |
/users |
新增用户 |
PUT |
/users/1 |
修改 id=1 的用户 |
DELETE |
/users/1 |
删除 id=1 的用户 |
JSON 文件"] -->|"json-server 启动"| B["RESTful API
http://localhost:3000"] C["前端 fetch()"] -->|"GET /users"| B B -->|"JSON 响应"| C
在这个项目中,前端目前用的是
common.js里硬编码的数组。但架构上已经准备好了------一旦把数据源从常量数组切换为fetch('/users'),就是标准的前后端分离应用。
Prompt 思考:AI 时代的高效协作
什么是 Prompt 思考?
Prompt 是你与 AI 之间的"需求文档"。写好 prompt,和写好代码需求一样重要------输入决定输出。
'帮我写个页面'"] --> B["AI 随便写
大概率不是你要的"] C["精确的 prompt
'写一个用户列表页
带 HTML 语义标签
引入 Bootstrap 表格
JS 动态渲染数据'"] --> D["AI 精准输出
一次到位"]
本项目 README 中的 Prompt 思维
| Prompt 关键词 | 触达的知识点 | 本项目落点 |
|---|---|---|
| "页面好看" | Bootstrap CSS 框架 | bootstrap.min.css CDN 引入 + 栅格系统 |
| "结构良好 搜索引擎友好" | HTML 语义化标签 | <header> <main> <aside> <footer> <thead> <tbody> |
| "不要 div 满天飞" | 块级元素做盒子,语义标签替代 div | 整个 index.html 只用了一个 <div> |
好 Prompt 的四个要素
- 给出上下文 --- "我正在做一个 user-chat 项目,前端三件套、后端 json-server"
- 明确技术栈 --- "用 Bootstrap 3 做样式,原生 JS 操作 DOM"
- 描述期望效果 --- "表格有斑马条纹、居中显示、数据动态渲染"
- 限定边界条件 --- "不要用 div 满天飞,用语义化标签"
一个反直觉的发现:你写得越"啰嗦"的 prompt,AI 写得越快越好。因为 AI 不是在"猜"你的意图------它是在执行你的规格说明。
总结
回顾这个 user-chat 项目,一条清晰的全栈开发链路浮出水面:
fe/ vs backend/"] end subgraph 组织层 B["模块化
一个目录一个职责
一个文件一件事"] end subgraph 前端层 C["HTML 语义化
header/main/aside/footer/table"] D["CSS 框架
Bootstrap 栅格 + 表格"] E["DOM 编程
querySelector + innerHTML"] end subgraph 后端层 F["json-server
JSON 文件 → RESTful API"] end subgraph 协作层 G["Prompt 思考
精确的需求描述 → 高效的 AI 产出"] end A --> B B --> C B --> D B --> E A --> F C --> G D --> G
- 前后端分离是架构的骨架------前端管 UI,后端管数据,互不耦合。
- 模块化是代码的组织原则------每个目录有职责,每个文件做一件事。
- HTML 语义化是页面的"说明书"------让搜索引擎、辅助设备、其他开发者都能读懂你的意图。
- Bootstrap 是颜值的快捷键------一行 CDN 让页面从"能用"变"好看"。
- DOM 编程是前端的基本功------不依赖框架,用原生 JS 完成数据渲染。
- Prompt 思考是 AI 时代的核心技能------输入的质量决定了输出的质量。
最终建议:动手能力是最好的老师。打开 VS Code,照着这个项目结构,亲手写一遍 HTML + CSS + JS + json-server------当你看到数据从 JSON 文件一路"流"到浏览器页面的那一刻,前后端分离的概念就真正内化了。