从 HTML 到 Vite:现代前端开发到底解决了什么问题?

3306 字
17 分钟
从 HTML 到 Vite:现代前端开发到底解决了什么问题?

前言#

前端开发并不是一开始就复杂的。

最开始,我们只需要写 HTML、CSS 和 JavaScript,就能做出一个可以运行的网页。

但随着项目变大,文件会越来越多,代码之间的依赖关系会越来越复杂,本地开发、上线构建、浏览器缓存等问题也会陆续出现。

这篇文章就从一个普通网页的组成讲起,一步步说明:为什么现代前端需要模块化,为什么需要构建工具,以及 Vite 到底解决了什么问题。


从最简单的网页开始#

一个普通网页通常由三部分组成:HTML、CSS 和 JavaScript。

HTML 负责页面结构,CSS 负责页面样式,JavaScript 负责交互逻辑。

一个很小的页面,可以把它们都写在同一个 HTML 文件里;但项目稍微变大,这个文件就会越来越难维护。

所以更常见的做法,是把它们拆成不同文件:

<link rel="stylesheet" href="style.css" />
<script src="main.js"></script>

这样做之后,结构、样式和逻辑被分开了,代码确实更清晰。但新的问题很快出现:当 JavaScript 文件越来越多时,脚本的加载顺序会变得非常重要。

比如 a.js 里定义了一个变量,b.js 里要使用它,那么 a.js 就必须写在 b.js 前面。顺序一旦错了,页面运行时就可能报错:变量不存在、函数未定义。

如果项目里只有两三个脚本,这个问题还可以靠人脑记住。可如果项目里有几十个甚至上百个 JS 文件,手动维护它们的引用顺序就会非常痛苦。

模块化:让文件之间的关系写清楚#

为了解决这个问题,现代前端引入了一个非常重要的基础能力:模块化。

模块化的核心思想是:每个文件只暴露自己想让外部使用的内容,其他文件需要什么,就显式地导入什么。

例如:

utils.js
export function add(a, b) {
return a + b
}
main.js
import { add } from './utils.js'
console.log(add(1, 2))

这样一来,文件之间的依赖关系就不再依靠 HTML 里的 <script> 顺序来维持,而是直接写在 JavaScript 代码里。

这就是 ES Modules,也就是我们常说的 ESM。export 负责导出,import 负责导入。

模块化带来的第一个变化:不能再直接双击打开 HTML#

使用普通 <script> 标签时,很多简单页面可以直接双击 HTML 文件运行,也就是通过 file:// 协议打开。

但如果你使用了 ESM:

<script type="module" src="main.js"></script>

情况就不一样了。

浏览器在加载模块时,会按照更严格的规则处理文件请求。通过 file:// 打开页面时,模块之间的导入很容易因为同源策略或 CORS 限制而加载失败。

所以,使用模块化之后,我们通常不能再依赖“直接双击 HTML 文件”来开发页面,而是需要通过一个本地 HTTP 服务来访问页面。

也就是说,页面应该通过类似这样的地址打开:

http://localhost:5173

而不是:

file:///C:/project/index.html

项目变大后,还会遇到哪些问题?#

到这里,我们其实已经从“写几个静态文件”进入了“现代前端项目”的世界。

这个阶段通常会遇到三个典型问题。

1. 本地开发需要一个服务器#

浏览器中的原生 ESM 开发通常应通过 HTTP 服务访问。如果每次修改代码后,都要手动上传到服务器再刷新页面,开发效率会非常低。

理想的开发体验应该是:在本地启动一个服务器,修改代码后浏览器自动刷新,甚至只更新变动的部分。

2. 上线时不能让浏览器请求太多零散文件#

开发阶段,我们希望文件拆得清楚,方便维护。

但上线之后,如果页面需要请求大量 CSS 和 JS 文件,首屏加载可能会变慢。虽然现代浏览器和 HTTP/2 已经缓解了这个问题,但生产环境仍然需要压缩、拆分和优化资源。

3. 浏览器缓存可能导致用户拿到旧文件#

浏览器会缓存 JS、CSS、图片等静态资源。这样可以加快第二次访问速度,但也会带来一个问题:代码明明已经更新了,用户浏览器里却还在使用旧文件。

一个常见解决方案是给文件名加上 hash,也叫文件指纹。

例如:

main.8d3f4a1c.js
style.6a91b2ef.css

只要文件内容发生变化,hash 就会变化,文件名也会变化。浏览器会把它当成一个新文件重新下载。

Vite:现代前端开发的基础工具#

为了解决上面这些问题,我们会引入构建工具。现在非常常用的一个构建工具,就是 Vite。

需要注意的是,Vite 不是 React、Vue 这种 UI 框架。它不负责规定页面怎么写,而是负责开发服务器、模块处理和生产构建。

Vite 主要做两类事情:开发阶段提升效率,生产阶段优化资源。

开发阶段:启动本地服务器#

Vite 会在本地启动一个开发服务器。你可以通过 http://localhost:5173 访问项目,而不是直接双击 HTML 文件。

这样就解决了 ESM 在 file:// 协议下的加载问题。

同时,Vite 还支持热更新,也就是 HMR。修改代码后,浏览器可以快速看到变化,不需要你手动重新部署。

生产阶段:打包、压缩、加文件指纹#

开发时,我们希望代码拆得细,文件职责清楚。

上线时,我们希望资源更适合浏览器加载。Vite 在构建生产版本时,会对代码进行打包、压缩和优化,并为输出文件生成带 hash 的文件名。

最终生成的文件通常会放在 dist 目录中。这个目录里的内容,才是要部署到服务器上的生产版本。

为什么使用 Vite 前要安装 Node.js?#

Vite 本质上是一个运行在 Node.js 环境里的前端工具。

JavaScript 原本主要运行在浏览器里,用来操作页面。但如果我们想在浏览器之外运行 JavaScript,比如执行构建工具、启动开发服务器、安装第三方库,就需要 Node.js。

你可以把 Node.js 理解成“让 JavaScript 在电脑本地运行的环境”。

安装 Node.js 后,可以在终端里检查版本:

Terminal window
node -v
npm -v

如果能看到版本号,就说明安装成功了。

这里的 npm 是 Node.js 自带的包管理工具。它的作用类似于 Python 里的 pip,用来安装和管理 JavaScript 生态里的第三方库。

如何在项目里安装 Vite?#

进入项目文件夹后,先初始化项目:

Terminal window
npm init -y

执行后,项目里会出现一个 package.json 文件。它用来记录项目名称、版本、脚本命令、依赖库等信息。

然后安装 Vite:

Terminal window
npm install -D vite

这里的 -D 表示把 Vite 安装为开发依赖,也就是写入 devDependencies

所谓“开发依赖”,不是说它只能安装在你自己的电脑上,而是说它只在开发和构建阶段需要。

如果选择在服务器上执行 npm run build,服务器在构建阶段也需要安装 Vite,所以这时要安装 devDependencies。默认执行 npm install 会安装它们。

但网站真正运行起来以后,浏览器访问的是 dist 里的静态文件,Nginx 只负责把这些文件返回给浏览器,并不需要继续运行 Vite。

安装完成后,项目里通常会多出两个东西:

node_modules/
package-lock.json

安装 Vite 后,项目目录里出现 package-lock.json 和 node_modules
安装 Vite 后,项目目录里出现 package-lock.json 和 node_modules

node_modules 是第三方库实际存放的位置。Vite 以及 Vite 依赖的其他库,都会安装在这里。

node_modules 中除了 Vite,还会包含它依赖的其他包
node_modules 中除了 Vite,还会包含它依赖的其他包

package-lock.json 用来锁定依赖版本,保证其他人安装项目依赖时,尽量得到一致的结果。

补充一下,如果是从零创建一个新项目,也可以直接使用 Vite 官方脚手架:

Terminal window
npm create vite@latest

它会帮你生成基础项目结构。本文使用 npm initnpm install -D vite,是为了更清楚地说明 Vite 是如何作为项目依赖被安装进来的。

Vite 命令从哪里来?#

安装 Vite 后,node_modules/.bin 目录里会出现可执行命令。

在 Windows 下,你可能会看到类似这样的文件:

node_modules\.bin\vite.cmd

它就是本地项目里的 Vite 命令。

node_modules/.bin 里的 vite.cmd、vite.ps1 等可执行入口
node_modules/.bin 里的 vite.cmd、vite.ps1 等可执行入口

不过实际开发中,我们通常不会手动去执行这个路径,而是把命令写进 package.jsonscripts 里。

例如:

{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
}

之后就可以这样使用:

Terminal window
npm run dev
npm run build
npm run preview

npm run dev 用来启动本地开发服务器。启动成功后,终端会显示本地访问地址,例如 http://localhost:5173/

Vite 开发服务器启动成功后,会显示本地访问地址
Vite 开发服务器启动成功后,会显示本地访问地址

npm run build 用来生成生产环境文件。

npm run preview 用来在本地启动一个服务器,检查构建后的生产版本是否正常;它不是正式的生产服务器。

补充:构建后的 dist 如何部署到服务器?#

一种常见做法是:服务器拉取源码后,在服务器上安装依赖并执行构建,而不是把 dist 提交到 Git 仓库。

具体来说,Git 仓库里只保存项目源码和配置文件,distnode_modules 都放进 .gitignore

node_modules 不提交,是因为它体积很大,而且可以根据 package.jsonpackage-lock.json 重新安装。

dist 不提交,是因为它是构建产物,可以随时通过源码重新生成。

所以一次典型的服务器部署流程是:

Terminal window
git pull
npm install
npm run build

注意:如果服务器负责执行 npm run build,就不能在构建前只安装 production 依赖。因为 Vite 在 devDependencies 中,构建阶段仍然需要它。

执行完 npm run build 后,服务器上会生成新的 dist 目录。

然后在 Nginx 中把网站根目录指向这个 dist 文件夹,并把入口文件设置为 index.html

例如:

server {
listen 80;
server_name example.com;
root /var/www/my-project/dist;
index index.html;
}

这样浏览器访问网站时,Nginx 返回的就是 Vite 构建后的生产文件。

如果后续项目使用前端路由,例如 React Router,还需要让 Nginx 在找不到具体文件时回退到 index.html

总结#

现代前端开发并不是一开始就复杂的。它是项目规模变大后,为了解决实际问题一步步演化出来的。

最开始,我们只需要 HTML、CSS 和 JavaScript。

后来,文件越来越多,手动维护脚本顺序变得困难,于是有了模块化。

模块化让依赖关系更清楚,但也要求我们通过 HTTP 服务来开发页面,于是需要本地开发服务器。

项目上线时,还需要打包、压缩、文件指纹和缓存处理,于是构建工具就变得非常重要。

Vite 解决的正是这些问题:开发时提供快速的本地服务器和热更新,上线前生成优化后的生产资源。

所以,理解 Vite 的关键不是记命令,而是理解它为什么出现:它是在帮我们把“适合开发的代码”,转换成“适合上线的资源”。

学完 Vite 之后,下一步学什么#

学到这里,我们已经解决了一部分“工程化”的问题。

Vite 帮我们解决的是开发和构建:本地服务器、模块化、热更新、打包、压缩、文件指纹。

也就是说,Vite 主要回答的是:

项目怎么开发?
代码怎么组织成模块?
上线前怎么构建成生产资源?

但 Vite 并不会直接解决“页面本身如何组织”的问题。

当页面越来越复杂时,我们会遇到新的麻烦:按钮、表单、列表、弹窗、用户状态、加载状态都混在一起。如果继续手动操作 DOM,代码会很快变得难以维护。

这时就需要 React。

React 是一个用于构建用户界面(UI)的 JavaScript 库,也常被称为前端框架;它的核心思想是用组件来组织页面。

React 关注的是另一个层面:如何把页面拆成组件,如何让数据传入组件,如何让状态变化后页面自动更新。

所以,Vite 和 React 解决的是两个不同问题:

Vite:解决项目开发、构建、部署的问题
React:解决页面组织、数据驱动、状态更新的问题

也正因为如此,学完 Vite 之后,继续学习 React 是很自然的一步。

这条现代前端学习路线可以继续往下走:

HTML/CSS/JS
→ Vite
→ React(或 Vue、Svelte 等)
→ Next.js 等应用框架

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
从 HTML 到 Vite:现代前端开发到底解决了什么问题?
https://hp-patience.github.io/posts/html-to-vite-modern-frontend/
作者
Celyn
发布于
2026-08-17
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Profile Image of the Author
Celyn
记录 AI、前后端与自动化学习,用费曼学习法把知识讲清楚。
公告
欢迎来到 Celyn 的博客!专注于AI大模型、深度学习与编程技术分享。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
19
分类
12
标签
47
总字数
45,991
运行时长
0
最后活动
0 天前

文章目录