打包工具解决什么问题
打包工具解决什么问题
没有打包工具时的问题
早期前端只能这样引入代码:
<script src="jquery.js"></script>
<script src="utils.js"></script>
<script src="app.js"></script>
带来的问题:
- 全局变量污染:所有 JS 共享同一个全局作用域
- 依赖顺序问题:必须手动保证 script 顺序正确
- HTTP 请求过多:100 个文件 = 100 次请求,首屏很慢
- 无法使用模块化:
import/require浏览器不支持(早期) - 新语法不兼容:TypeScript、JSX、ES6+ 浏览器不认识
- 资源处理麻烦:CSS、图片、字体等资源无法模块化管理
打包工具做了什么
1. 模块化支持
// 开发时可以这样写
import { add } from "./math.js";
import React from "react";
// 打包工具分析依赖,合并成浏览器能认识的代码
2. 语法转换(Transpile)
// 开发时写 TSX/JSX
const App = () => <div>Hello</div>;
// 打包后转成浏览器能执行的 JS
const App = () => React.createElement("div", null, "Hello");
3. 代码合并 + 压缩
开发时:100 个文件
打包后:1~3 个 bundle.js(体积压缩 60%~80%)
4. Tree Shaking(摇树优化)
import { add, subtract } from "./math";
// 只用了 add,subtract 不会打包进去
5. 资源处理
import logo from "./logo.png"; // 图片转 base64 或生成 hash 文件名
import styles from "./App.css"; // CSS 模块化处理
6. 代码分割(Code Splitting)
// 按需加载,不是一次性全部下载
const Page = lazy(() => import("./Page"));
打包的最终产物是什么
dist/
├── index.html // 入口 HTML(引用下面的资源)
├── js/
│ ├── main.a1b2c3.js // 主包(含核心逻辑)
│ ├── vendor.x9y8z7.js // 第三方库(React 等)
│ └── chunk.d4e5f6.js // 懒加载的代码块
├── css/
│ └── main.a1b2c3.css // 合并压缩后的样式
└── assets/
├── logo.3f4a5b.png // hash 命名的图片
└── font.woff2 // 字体文件
- 文件名带 hash:
main.a1b2c3.js,内容变了 hash 就变,用于缓存控制(浏览器缓存旧文件,新文件强制下载) index.html:自动注入打包后的 script 和 link 标签
开发环境 vs 生产环境产物区别
| 开发环境 | 生产环境 | |
|---|---|---|
| 代码压缩 | ❌ | ✅ |
| Source Map | ✅(方便调试) | 可选 |
| Tree Shaking | ❌ | ✅ |
| 文件 hash | ❌ | ✅ |
| 构建速度 | 优先快 | 优先体积小 |
