Skip to content

实训:构建工具

元信息

  • 目标:亲手完成"无构建 → vite 工程化"的对照实验——先用原生 ESM + importmap 免构建搭一个页面,再用 vite 重建同一页面,体验 dev server/HMR/打包产物,理解构建工具到底替我们做了什么
  • 关键概念:脚手架、dev server、HMR、build 产物、importmap、按需编译
  • 关联阶段:cp3
  • 常见误区:以为 vite 是"又一个要背配置的工具"(脚手架开箱即用,零配置即可跑通全流程);以为构建只是压缩代码(模块解析、兼容转译、产物哈希命名都在其中)

任务

  • vite 从零搭一个工程化项目,并与"无构建"方式做同题对照,回答:构建工具替我们做了什么?

步骤 0:准备

确认 Node 环境(18+),国内网络可先切镜像源:

bash
node -v        # 应 >= 18
npm config set registry https://registry.npmmirror.com/
mkdir build-lab && cd build-lab   # 实验总目录,两种方式各占一个子目录

步骤 1:无构建方式(对照组)

利用原生模块ESM + importmap,不装任何工具,直接写一个页面。

no-build/ 目录,写入 index.html

<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>

同目录写 main.js

javascript
import dayjs from 'dayjs'

document.getElementById('time').textContent =
  '现在是 ' + dayjs().format('YYYY-MM-DD HH:mm:ss')

启动一个静态服务器(二选一)并访问:

bash
npx serve no-build        # 或 python3 -m http.server -d no-build 8000
  • 记录体验:改一行 main.js,浏览器要手动刷新才能看到;依赖靠 importmap 手工映射 CDN 地址;没有任何转译与优化。

步骤 2:用 vite 重建同一页面(实验组)

回到 build-lab/,用脚手架生成项目:

bash
npm create vite@latest vite-demo -- --template vanilla
cd vite-demo
npm install
npm run dev
  • 浏览器打开终端提示的地址(默认 http://localhost:5173/),看到脚手架示例页即成功。

清空 src/index.html 中的示例内容,把步骤 1 的页面搬进来,体会差异:

  1. index.html不再需要 importmap —— 裸模块名 dayjs 由 vite 解析:
<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>
  1. 安装依赖并改写 src/main.js(CDN 地址换成 npm 包名):
bash
npm i dayjs
javascript
import dayjs from 'dayjs'
import './style.css'

document.getElementById('time').textContent =
  '现在是 ' + dayjs().format('YYYY-MM-DD HH:mm:ss')
  1. 新建 src/style.css,保存后不刷新页面看样式与文本即时生效——这就是 HMR:
css
h1 { color: #646cff; }

步骤 3:打包产物

执行生产构建并查看产物:

bash
npm run build     # 输出到 dist/
npx serve dist    # 预览生产版本
ls dist/assets    # 观察文件名
  • 打开 dist/index.htmldist/assets/ 下的 js:index.html 只引了一个带哈希的 js(如 index-BwUDq0qB.js);
  • js 内容是压缩后的——dayjs、main.js 已被合并、压缩、混淆;
  • 思考:步骤 1 的方式要把这套优化全手工做一遍吗?

对照与结论

无构建(步骤 1)vite(步骤 2-3)
依赖来源CDN + importmap 手工映射npm i,名字即地址
改代码后手动刷新HMR 免刷新、保状态
兼容/转译无(新语法老浏览器直接挂)构建期按目标环境转译
上线产物源码即产物合并、压缩、哈希命名的 dist
代价零工具链需要 Node 环境与 node_modules

结论一句话:开发期 vite 用原生 ESM 换即时反馈,生产期用打包换加载性能——见esbuild与vite

检查点(自查)

  • [ ] 步骤 1 页面能显示当前时间(importmap 生效)
  • [ ] 步骤 2 npm run dev 正常启动,改动 css/js 不刷新即生效
  • [ ] 步骤 3 dist/ 内只有一个入口 js 且为压缩版
  • [ ] 能口头回答:importmap 和 vite 各自解决了"裸模块名"问题的哪一半?

常见问题

  • npm create vite 卡住或报错:确认 Node >= 18;公司/校园网下先执行步骤 0 的镜像源设置。
  • 端口被占用npm run dev -- --port 5174 换端口。
  • HMR 不生效:确认是通过 http://localhost:5173/ 访问 dev server,而不是直接双击打开 index.html 文件。

延伸

  • 把个人项目的某个页面按本实训迁移到 vite(可不迁移整站);
  • 在 vite 项目里装一个新依赖(如 npm i lodash)并 import 使用,体会包管理;
  • 尝试 npm run build 后改一行代码再 build,对比 dist 里哈希文件名是否变化,理解缓存失效策略。