webpack与vite对比
- 构建方式
(1)webpack启动项目时,会根据配置文件中的入口(entry),分析出项目所有依赖关系,然后打包成一个或多个文件(bundle.js),交给浏览器去加载渲染。在生产环境中优化 bundle,比如 Tree-shaking、Code Splitting。
项目越大,需要打包的东西越多,启动时间越长。
(2)使用vite运行项目时,首先会用esbuild进行预构建,将所有模块转换为es module,不需要对整个项目进行编译打包,而是在浏览器需要加载某个模块时,拦截浏览器发出的请求,根据请求进行按需编译,然后返回给浏览器。
生产环境:借助 Rollup 打包,天然支持 ESModule,优化输出体积。
项目大小对vite启动速度的影响很小。
- 热更新
(1)webpack项目中,每次修改文件,都会对整个项目重新进行打包
(2)Vite 热更新的实现依赖 原生 ES Module (ESM) 和 WebSocket 通信:
- 启动 Dev Server
Vite 启动一个开发服务器,基于 koa。同时在浏览器和服务器之间建立一个 WebSocket 连接。
- 文件变更监听
使用 chokidar 监听项目文件(.vue、.js、.ts、.css 等)。一旦文件变更,通过 WebSocket 向浏览器发送更新消息(包含变化的模块路径、更新类型等)。
- 浏览器接收并处理
浏览器端 Vite 注入了 HMR runtime(一个小的客户端脚本)。它会拦截 WebSocket 消息,替换对应的模块。
Webpack
- loader
告诉 webpack 如何处理非 JavaScript 文件(如 .css, .vue, .ts, .png 等),
并把它们转换成浏览器可以识别的 JS 模块。
css-loader:把.css文件内容转换为 JS 中的字符串模块;babel-loader:把 ES6+ 代码编译为兼容的 ES5;file-loader/url-loader:处理图片、字体等资源。sass-loader:把 Sass 转成 CSS
module.exports = {
module: {
rules: [
{
test: /\.js$/, // 匹配文件类型
use: 'babel-loader', // 使用哪个 loader 处理
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'] // 多个loader从右往左执行
}
]
}
}
- plugin
Plugin 是 webpack 的插件系统, 通过监听 webpack 的生命周期钩子(hooks) ,
在构建过程的不同阶段,扩展 Webpack 的功能
- terser-webpack-plugin压缩 JS
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { DefinePlugin } = require('webpack');
module.exports = {
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new DefinePlugin({ VERSION: JSON.stringify('1.0.0') })
]
};
Rollup
Rollup 是一个 ES Module 打包工具,特别适合用于构建 库(Library) 和 框架。与webpack相比, Rollup 缺少开发服务器、HMR、复杂资源处理等功能
- Tree-shaking
能在打包时完全移除未使用的函数/变量,生成非常干净的代码。
- Rollup 可以把源码打包成多种格式:
| 格式名 | 全称 | 适用场景 | 特点 |
|---|---|---|---|
es / esm | ES Module | 现代浏览器、ESM 环境(如 Node 14+) | 使用 import / export 语法 |
cjs | CommonJS | Node.js (旧版)、Webpack (require) | 使用 require() / module.exports |
umd | Universal Module Definition | 同时支持浏览器 + Node + AMD | 可挂到全局变量上 |
iife | Immediately Invoked Function Expression | 浏览器直接引入 <script> | 立即执行函数形式,适合全局变量输出 |
amd | Asynchronous Module Definition | RequireJS、老 AMD 体系 | 很少使用 |
system | SystemJS | 动态模块加载场景 | 适合 SystemJS runtime |
- commonjs与esmodule的区别
| 特性 | CommonJS | ES Module |
|---|---|---|
| 语法 | require / module.exports | import / export |
| 加载 | 同步加载 | 静态/异步加载 |
| 循环依赖 | 返回部分对象 | 实时绑定,保证值更新 |
| 浏览器原生支持 | ❌ | ✅ <script type="module"> |
| tree-shaking | ❌ | ✅ 支持 |
| 默认导出 | 通过 module.exports | export default |
| Node.js 默认 | .js | .mjs 或 "type":"module" |