阅读完本节后,你将会收获:
- 理解 HTML、CSS、JavaScript 三者如何协同工作构建网页
- 了解代码格式从单文件到模块化、TypeScript 的演变过程
- 知道什么时候用简单格式,什么时候用复杂格式
- 理解为什么 AI 生成的代码需要特定的运行环境
序言中提到的 AI 有时给出
.html文件,有时给出.ts文件,这是因为代码格式随着项目复杂度在演变。
网页就像一个三明治,由三层组成:
graph TB
A[HTML 结构层] --> B["标题/按钮"]
C[CSS 样式层] --> D["颜色/字体"]
E[JavaScript 行为层] --> F["点击事件"]
B --> G[最终呈现的网页]
D --> G
F --> G
style A fill:#e3f2fd
style C fill:#fff3e0
style E fill:#f3e5f5
一个完整的例子:
<!DOCTYPE html>
<html>
<head>
<style>
/* CSS: 样式层 — 长什么样 */
.box { background: #f0f0f0; padding: 20px; }
.count { font-size: 24px; }
</style>
</head>
<body>
<!-- HTML: 结构层 — 有什么内容 -->
<div class="box">
<span class="count">0</span>
<button>增加</button>
</div>
<script>
/* JavaScript: 行为层 — 怎么交互 */
let count = 0;
document.querySelector('button').addEventListener('click', () => {
count++;
document.querySelector('.count').textContent = count;
});
</script>
</body>
</html>
把这三种代码写在一个 .html 文件里,就是单文件格式——双击就能运行,不需要安装任何东西。
你可能试过用 Ctrl + S 保存一个喜欢的网页,再次打开时出现不同情况:
| 现象 | 原因 |
|---|---|
| 完全正常 | 单文件格式,所有代码都在一个 HTML 里 |
| 有样式但点不了 | CSS 在本地,JS 从服务器加载,断网失效 |
| 样式全无 | CSS 和 JS 都从服务器加载,本地只有空壳 |
| 完全打不开 | 现代单页应用,需要服务器才能运行 |
现代网站(如微博、B 站)使用 React/Next.js 等框架开发:代码分离在不同文件,内容通过 JS 动态获取,保存下来的只是一个空 HTML 壳子。
graph LR
A[传统网页] --> B[所有代码<br/>在一个 HTML]
B --> C[保存后可离线打开]
D[现代网页] --> E[代码分离<br/>需要服务器]
E --> F[保存后只有空壳]
graph LR
A["单文件 HTML<br/>(结构+样式+逻辑)"] --> B["分离文件<br/>(HTML+CSS+JS)"]
B --> C["模块化<br/>(import/export)"]
C --> D["TypeScript工程化<br/>(类型+构建)"]
💡 练习:点击时间轴上的不同阶段,观察代码格式如何从机器语言演变为现代 JavaScript。
🎯 核心概念:代码格式越来越接近人类语言,但运行前需要更多转换步骤。
所有代码在一个 .html 文件中。
适用场景:简单 Demo、学习概念、快速原型
局限:代码超过 200 行后就难以维护
结构(HTML)、样式(CSS)、逻辑(JS)分开:
project/
├── index.html
├── style.css
└── script.js
适用场景:代码超过 200 行,或多个页面共享样式
局限:文件依赖关系需要手动管理,无法使用 npm 包
使用 import/export 组织代码:
// utils.js
export function formatDate(date) {
return date.toISOString();
}
// app.js
import { formatDate } from './utils.js';
适用场景:代码有重复逻辑,或多人协作
局限:浏览器需要构建工具支持
使用 TypeScript + 构建工具:
// utils.ts
export function formatDate(date: Date): string {
return date.toISOString();
}
适用场景:复杂逻辑、多人协作、长期维护的项目
为什么 AI 喜欢用 TypeScript?
TypeScript 代码不能直接在浏览器运行,必须经过编译:
.ts/.tsx 文件 → TypeScript 编译器 → .js 文件 → 浏览器执行
开发时:pnpm dev 自动编译
上线时:pnpm build 打包优化
| 项目复杂度 | 推荐格式 | 运行方式 |
|---|---|---|
| 简单 Demo、一次性脚本 | 单文件 HTML | 直接打开 |
| 中小型项目 | 模块化 JS | 需要 build |
| 复杂应用、多人协作 | TypeScript + 框架 | 需要 dev server |
原则:能用简单方案就不用复杂方案,但不要在复杂项目上强行用简单方案。
让 AI 知道你的需求,它会选择合适的格式:
"生成一个单文件 HTML 的计数器" → 单文件,双击可运行
"生成一个任务管理应用" → TypeScript 项目,需要 pnpm dev
TypeScript 是 JavaScript 的升级版,增加了类型检查。
// TypeScript 写代码时会指出错误
const count: number = "hello"; // ❌ 编辑器标红
// JavaScript 要运行后才报错
const count = "hello";
count.toFixed(2); // 💥 运行时崩溃
你不需要记住语法,只需要知道:
.ts 或 .tsx 文件需要通过 pnpm dev 运行: string 这种类型标注时,知道这是 TypeScript 即可复杂项目用单文件无法维护。想象一个 1000 行的 HTML 文件,修改样式需要在 500 行处找对应的 <style> 标签——这是灾难。模块化让每个文件只负责一件事。
首先判断代码类型:
单文件 HTML:
# 直接双击,或
open index.html # Mac
start index.html # Windows
TypeScript 项目:
pnpm install # 安装依赖
pnpm dev # 启动开发服务器
如果还是报错,把错误信息发给 AI,它会告诉你具体原因。